Java基础——多线程:三种实现方式

来源:互联网 发布:mac抹掉磁盘安装high 编辑:程序博客网 时间:2024/06/01 09:51

Java多线程的三种实现方式:继承继承Thread类、实现Runnable接口、使用ExecutorService、Callable、Future实现有

回结果的多线程。其中前两种方式线程执行完后都没有返回值,只有最后一种是带返回值的。

1、继承Thread类:

        实质上是实现Runnable接口的一个实例,启动线程的唯一方法就是通过Thread类的start()实例方法。start()方法是一个native方法,它将启动一个新线程,并执行run()方法。这种方式实现多线程很简单,通过自己的类直接extend Thread,并复写run()方法,就可以启动新线程并执行自己定义的run()方法。例如:

public class ThreadUtil extends Thread{

//构造方法传参

    public void run(){

//该处写要实现的方法        System.out.println("thread.run()");
    }
}

//启用多线程

ThreadUtil myTh = new ThreadUtil();
        ThreadUtil myTh1 = new ThreadUtil();
        myTh.start();
        myTh1.start();

2、实现Runnable接口:

如果自己的类已经extends另一个类,就无法直接extends Thread,此时,必须实现一个Runnable接口,如下:

public class ThreadUtil extends MD5 implements Runnable{

//构造方法传参

    public ThreadUtil(){
        
    }
    public void run(){

//要实现的方法

        System.out.println("thread.run()");
    }
}

//启用多线程

ThreadUtil myTh = new ThreadUtil();
        ThreadUtil myTh1 = new ThreadUtil();
        Thread th = new Thread(myTh);
        Thread th1 = new Thread(myTh1);
        th.start();
        th1.start();

3、使用ExecutorService、Callable、Future实现有返回结果的多线程

ExecutorService、Callable、Future这个对象实际上都是属于Executor框架中的功能类,返回结果的线程是在JDK1.5中引入的新特征。可返回值的任务必须实现Callable接口,类似的,无返回值的任务必须Runnable接口。执行Callable任务后,可以获取一个Future的对象,在该对象上调用get就可以获取到Callable任务返回的Object了,再结合线程池接口ExecutorService就可以实现传说中有返回结果的多线程了。部分代码如下:

编写Callable类实现Callable接口:

...

import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch;

public class CallableUtil implements Callable<Map<String,List<Map<String, Object>>>> {

    //Map<String,List<Map<String, Object>>>返回值类型

    //参数

    private String flag;
    private Map<String,String> map;
    private CountDownLatch latch;
    //构造方法
     public CallableUtil(Map<String, String> map,String flag, CountDownLatch latch) {
             this.flag = flag;
             this.map = map;
            this.latch = latch;
        }

    public Map<String,List<Map<String, Object>>> call() throws Exception {

    //该处写要实现的方法,根据条件不同,该线程要实现的方法也不同,以达到提高效率的目的

    latch.countDown();// 完成工作,计数器减一

    ....

}}

调用上述类实现多线程:

...

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

//在要用到多线程处

//创建线程池

ExecutorService producerPool = Executors.newFixedThreadPool(4);//4代表线程数量

CountDownLatch latch = new CountDownLatch(4);// 协同

//获取Future对象

Future<?> f1 = null;
            Future<?> f2 = null;
            Future<?> f3 = null;
            Future<?> f4 = null;
            f1 = producerPool.submit(new CallableUtil(paramMap,"1", latch));
            f2 = producerPool.submit(new CallableUtil(paramMap,"2", latch));
            f3 = producerPool.submit(new CallableUtil(paramMap,"3", latch));
            f4 = producerPool.submit(new CallableUtil(paramMap,"4", latch));
            try {
                latch.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
                Thread.currentThread().interrupt();
            } finally {

            }

    //从Future对象上获取任务的返回值

    Map<String,List<Map<String, Object>>> map1 = (Map<String, List<Map<String, Object>>>) f1.get();
            Map<String,List<Map<String, Object>>> map2 = (Map<String, List<Map<String, Object>>>) f2.get();
            Map<String,List<Map<String, Object>>> map3 = (Map<String, List<Map<String, Object>>>) f3.get();
            Map<String,List<Map<String, Object>>> map4 = (Map<String, List<Map<String, Object>>>) f4.get();
            // 等待工作完成(关闭线程池)
            producerPool.shutdown();

    .......

以上就是Java实现多线程的三种方式。

原创粉丝点击