创建并启动有返回值的线程的步骤如下:
第一步:创建 Callable接口的实现类,并实现call()方法,该call()方法将作为线程执行体,且该call()方法有返回值,再创建 Callable实现类的实例 。从Java8开始,可以直接使用 Lambda表达式创建 Callable对象
第二步:使用FutureTask类来包装Callable对象,该FutureTask对象封装了该Callable对象的call方法的返回值
第三步:使用FutureTask对象作为Thread对象的target创建并启动新线程
第四步:通过FutureTask的get()方法获得子线程执行结束后的返回值
import java.util.concurrent.Callable;import java.util.concurrent.FutureTask; public class ThirdThread {public static void main(String[] args) {//ThirdThread rt=new ThirdThread();FutureTask<Integer> task=new FutureTask<Integer>((Callable<Integer>)()->{int i=0;for(;i<100;i++) {System.out.println(Thread.currentThread().getName()+"的循环变量i"+i);}return i;}) ;for(int i=0;i<100;i++) {System.out.println(Thread.currentThread().getName()+"的循环变量i为"+i);if(i==20) {new Thread(task,"有返回值的线程").start();;}}try {System.out.println("子线程的返回值"+task.get());}catch(Exception e) {e.printStackTrace();}} }创建线程的三种方式的对比:采用Runnable、Callable接口的方式创建多线程的优缺点:
优点:采用继承 Thread类的方式创建多线程的优缺点:
1、线程类只是实现了 Runnable接口或 Callable接口,还可以继承其他类
2、在这种方式下,多个线程可以共享同一个 target对象,所以非常适合多个相同线程来处理同一份资源的情况,从而可以将CPU、代码和数据分开,形成清晰的模型,较好地体现了面向对象的思想 。
缺点:
编程稍稍复杂,如果需要访问当前线程,则必须使用Thread.currentThread()方法 。
优点:线程的生命周期:新建和就绪状态:
编写简单,如果需要访问当前线程,则无须使用 Thread.current Thread()方法,直接使用this即可获得当前线程
缺点:
因为线程已经继承了Thread类,所以不能再继承其他类
当程序使用new关键字创建一个线程后,该线程就处于新建状态 。
当线程对象调用了start()方法后,该线程就处于就绪状态 。
运行和阻塞状态:
如果处于就绪状态的线程获取了CPU,开始执行run()方法的线程执行体,则该线程处于运行状态 。
当线程调用sleep(),调用一个阻塞式IO方法,线程会被阻塞
死亡状态:
1、run()或者call()方法执行完成,线程正常结束
2、线程抛出一个未捕获的Exception或Error
3、直接调用该线程的stop方法来结束该线程——该方法容易导致死锁,不推荐使用

文章插图
线程状态转化图
四、控制线程join线程Thread提供了让一个线程等待另一个线程完成的方法——join方法 。当在某个程序执行流中调用其直到被 join方法加入的join线程执行完为止
public class JoinThread extends Thread {//提供一个有参数的构造器,用于设置该线程的名字public JoinThread(String name) {super(name);}//重写run方法,定义线程体public void run() {for(int i=0;i<10;i++) {System.out.println(getName()+" "+i);}}public static void main(String[] args) throws InterruptedException {//启动子线程new JoinThread("新线程").start();for(int i=0;i<10;i++) {if(i==5) {JoinThread jt=new JoinThread("被join的线程");jt.start();//main线程调用了jt线程的join方法,main线程//必须等jt执行结束才会向下执行jt.join();}System.out.println(Thread.currentThread().getName()+" "+i);}}}运行结果main 0main 1main 2main 3main 4新线程 0新线程 1新线程 2新线程 3被join的线程 0新线程 4被join的线程 1新线程 5被join的线程 2新线程 6被join的线程 3新线程 7被join的线程 4新线程 8被join的线程 5新线程 9被join的线程 6被join的线程 7被join的线程 8被join的线程 9main 5main 6main 7main 8main 9后台线程:有一种线程,它是在后台运行的,它的任务是为其他的线程提供服务,这种线程被称为“后台线程( Daemon Thread)”,又称为“守护线程”或“精灵线程” 。JVM的垃圾回收线程就是典型的后台线程 。后台线程有个特征:如果所有的前台线程都死亡,后台线程会自动死亡 。
调用 Thread对象的 setDaemon(true)方法可将指定线程设置成后台线程 。下面程序将执行线程设置成后台线程,可以看到当所有的前台线程死亡时,后台线程随之死亡 。当整个虚拟机中只剩下后台线程时,程序就没有继续运行的必要了,所以虚拟机也就退出了 。
推荐阅读
- 唐僧取经是哪个朝代的事
- 皎然贬酒褒茶道,唐代位嗜茶的诗僧皎然介绍
- 考上清华北大的人特点是什么?
- 佛教僧侣茶俗的繁荣,四川民俗中的茶俗谚语介绍
- 高僧|唐朝一富家公子,酷爱乘船钓鱼,从不去风月之地,后成一代高僧
- 茶艺的缘起及发展,唐代位嗜茶的诗僧皎然介绍
- 机器人|扫地机器人并非万能!有些活干不了
- 能与清华北大PK的大学专业
- 茶叶的制作过程详解,严君谢僧寄茶茶叶茶诗详解
- 茶与僧侣的不解之缘,佛中有茶
