Java多线程的运用有三种要领:继续Thread类、完成Runnable接口和运用Callable和Future建立线程。
一、继续Thread类
完成体式格局很简单,只须要建立一个类去继续Thread类然后重写run要领,在main要领中挪用该类实例对象的start要领即可完成多线程并发。代码:
public class MyThread extends Thread { @Override public void run(){ super.run(); System.out.println("实行子线程..."); } }
测试用例:
public class Test { public static void main(String[] args) { MyThread myThread = new MyThread(); myThread.start(); System.out.println("主线程..."); } }
运转效果:
固然,这里的效果不代表线程的实行递次,线程是并发实行的,假如多运转频频,打印递次大概会不一样。多线程的运转历程当中,CPU是以不确定的体式格局去实行线程的,故运转效果与代码的实行递次或许挪用递次无关,运转效果也大概不一样。
免费视频教程引荐:java进修视频
这里另有一个须要注重的点就是main要领中应当挪用的是myThread的start要领,而不是run()要领。挪用start()要领是通知CPU此线程已预备就绪能够实行,进而体系有时间就会来实行其run()要领。
而直接挪用run()要领,则不是异步实行,而是等同于挪用函数般按递次同步实行,这就失去了多线程的意义了。
二、完成Runnable接口
这类体式格局的完成也很简单,就是把继续Thread类改成完成Runnable接口。代码以下:
public class MyRunnable implements Runnable { @Override public void run() { System.out.println("实行子线程..."); } }
测试用例:
public class Test { public static void main(String[] args) { Runnable runnable = new MyRunnable(); Thread thread = new Thread(runnable); thread.start(); System.out.println("主线程运转完毕!"); } }
运转效果:
运转效果没啥好说的,这里main中能够看到真正建立新线程照样经由历程Thread建立:
Thread thread = new Thread(runnable);
这一步Thread类的作用就是把run()要领包装成线程实行体,然后依旧经由历程start去通知体系这个线程已预备好了能够部署实行。
三、运用Callable和Future建立线程
上面的两种体式格局都有这两个问题:
1、没法猎取子线程的返回值;
2、run要领不能够抛出非常。
为了处理这两个问题,我们就须要用到Callable这个接口了。说到接口,上面的Runnable接口完成类实例是作为Thread类的组织函数的参数传入的,以后经由历程Thread的start实行run要领中的内容。然则Callable并非Runnable的子接口,是个全新的接口,它的实例不能直接传入给Thread组织,所以须要另一个接口来转换一下。
Java5供应了Future接口来代表Callable接口里call()要领的返回值,并为Future接口供应了一个完成类FutureTask,该完成类的继续关联如图所示:
能够看到,该完成类不仅完成了Future接口,还完成了Runnable接口,所以能够直接传给Thread组织函数。
而关于FutureTask的组织函数以下:
所以这内里实在就是要比上一个要领再多一个转换历程,终究一样是经由历程Thread的start来建立新线程。有了这个思绪,代码就很轻易理解了:
import java.util.concurrent.Callable; public class MyCallable implements Callable { int i = 0; @Override public Object call() throws Exception { System.out.println(Thread.currentThread().getName()+" i的值:"+ i); return i++; //call要领能够有返回值 } }
测试:
import java.util.concurrent.Callable; import java.util.concurrent.FutureTask; public class Test { public static void main(String[] args) { Callable callable = new MyCallable(); for (int i = 0; i < 10; i++) { FutureTask task = new FutureTask(callable); new Thread(task,"子线程"+ i).start(); try { //猎取子线程的返回值 System.out.println("子线程返回值:"+task.get() + "\n"); } catch (Exception e) { e.printStackTrace(); } } } }
实行效果(部份):
相干文章教程引荐:java入门顺序
以上就是java中完成多线程的几种体式格局的细致内容,更多请关注ki4网别的相干文章!