java中多線程實現方式


  java中線程是經常會提到的問題,但是實際開發工作卻又很少用的技術(起碼本人用的比較少)。下面介紹幾種常見的線程實現方式

  1、繼承Thread類,重寫run方法

   我們通過集成Thread類並通過重寫run方法的方式實現線程,然后通過start方法啟動線程

  

public class MyThread extends Thread{

    @Override
    public void run() {
        System.out.println("================"+new Date());
    }

    public static void main(String[] args) {
        for(int i=0;i<10;i++){
            MyThread myThread = new MyThread();
            myThread.start();
        }
    }
}

運行main方法測試效果:

 

  2、通過實現Runable接口的方式

  Thread作為java中的線程類,其有一個Runable作為構造參數的構造方法,我們可以通過實現Runable接口,從而進一步實現線程。同樣是通過start啟動線程。

/**
 * 通過實現Runable接口
 */
public class MyRunableImpl implements Runnable{

    private String name;

    public MyRunableImpl(String name) {
        this.name = name;
    }

    @Override
    public void run() {
        System.out.println(name+"================"+new Date());
    }

    public static void main(String[] args) {
        for(int i=0;i<10;i++){
            MyRunableImpl myRunable = new MyRunableImpl("myRunable"+i);
            Thread t = new Thread(myRunable);
            t.start();
        }
    }
}

運行main方法測試效果:

 

   3、通過FutureTask實現線程

  此方式和第二種方式有點像,還是使用Thread(Runnable)構造方法,區別在於此處不用自己實現Runable,而是使用FutureTask。FutureTask實現了

RunnableFuture接口,而RunnableFuture接口又集成了Runable接口,所以我們也可以使用FutureTask做為構造參數創建線程。FutureTask支持兩種有參的構造方法,此處我們使用Future(Callable)。首先,我們需要創建一個類,該類需要實現Callable接口,實現call方法。

public class MyCallable implements Callable {

    private String name;

    public MyCallable(String name) {
        this.name = name;
    }

    @Override
    public Object call() throws Exception {
        System.out.println(name+"==============="+new Date());
        return name;
    }
}

測試類

public class FutureTaskTest {

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        for(int i=0;i<10;i++){
            MyCallable myCallable = new MyCallable("myCallable"+i);
            FutureTask futureTask = new FutureTask(myCallable);
            Thread t = new Thread(futureTask);
            t.start();
            Object o = futureTask.get();
            System.out.println("return value============"+o);
        }
    }
}

運行main方法測試效果:

 

 在線程啟動時會調用Callable接口的call方法。我們可以通過FutureTask.get()方法獲取call()的返回值。需要注意的是get方法會阻塞線程。

  4、使用Executors創建線程池

  Executors是java juc中的類,我們可以通過其創建線程池,並以此實現線程。此方式同樣需要一個Callable的實現類,此處我們還是使用第3中方法中的類。

public class ExecutorsTest {

    public static void main(String[] args) {
        ExecutorService executorService = Executors.newFixedThreadPool(10);
        List<Future<?>> list = new ArrayList<>();
        for(int i=0;i<10;i++){
            MyCallable myCallable = new MyCallable("myCallable"+i);
            Future submit = executorService.submit(myCallable);
            list.add(submit);
        }
        for(Future future:list){
            try {
                Object o = future.get();
                System.out.println("return value============="+o);
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            }
        }
        executorService.shutdown();
    }
}

我們通過Executors創建線程池,ExecutorService.submit(Callable)啟動線程。submit方法會返回一個Future對象,通過其get()方法可以獲取Callable實現類的call方法返回值。執行完上述操作后需要調用ExecutorService.shutdown方法,不然主線程會一直處於運行狀態。

執行main方法測試效果:

 

 以上就是常見的創建多線程的幾種方式。如果不對,對應大家評論留言。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM