java中線程是常常會提到的問題,可是實際開發工做卻又不多用的技術(起碼本人用的比較少)。下面介紹幾種常見的線程實現方式java
一、繼承Thread類,重寫run方法多線程
咱們經過集成Thread類並經過重寫run方法的方式實現線程,而後經過start方法啓動線程ide
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方法測試效果:測試
二、經過實現Runable接口的方式this
Thread做爲java中的線程類,其有一個Runable做爲構造參數的構造方法,咱們能夠經過實現Runable接口,從而進一步實現線程。一樣是經過start啓動線程。spa
/** * 經過實現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方法測試效果:線程
三、經過FutureTask實現線程3d
此方式和第二種方式有點像,仍是使用Thread(Runnable)構造方法,區別在於此處不用本身實現Runable,而是使用FutureTask。FutureTask實現了code
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方法會阻塞線程。
四、使用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方法測試效果:
以上就是常見的建立多線程的幾種方式。若是不對,對應你們評論留言。