栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

多线程

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

多线程

1.安全退出线程
1>设置退出标识

public class SetFlagTest extends Thread {

 public volatile  boolean exit = false;

 @Override
 public void run(){
     while (!exit){
  try {
      sleep(1000);
  } catch (InterruptedException e) {
      e.printStackTrace();
  }
  System.out.println("子线程执行中。。。");
     }
     System.out.println("子线程退出");
 }

 public static void main(String[] args) throws InterruptedException {
     SetFlagTest setFlagTest = new SetFlagTest();
     setFlagTest.start();
     System.out.println("主线程休眠3秒");
     sleep(3000);
     System.out.println("join() 代表让子线程执行完之后,才执行当前线程后续代码");
     
     System.out.println("线程退出");
 }

}

打印结果(子线程会一直执行,且可以看得出主线程和子线程互不影响执行)

主线程休眠3秒
子线程执行中。。。
子线程执行中。。。
join() 代表让子线程执行完之后,才执行当前线程后续代码
线程退出
子线程执行中。。。
子线程执行中。。。
子线程执行中。。。
子线程执行中。。。
子线程执行中。。。

修改标识以后就可以执行完,代码如下:

public class SetFlagTest extends Thread {

    public volatile  boolean exit = false;

    @Override
    public void run(){
 while (!exit){
     try {
  sleep(1000);
     } catch (InterruptedException e) {
  e.printStackTrace();
     }
     System.out.println("子线程执行中。。。");
 }
 System.out.println("子线程退出");
    }

    public static void main(String[] args) throws InterruptedException {
 SetFlagTest setFlagTest = new SetFlagTest();
 setFlagTest.start();
 System.out.println("子线程已经开启");
 System.out.println("主线程休眠3秒");
 sleep(3000);
 setFlagTest.exit=true;
 System.out.println("修改退出标志");
 System.out.println("join() 代表让子线程执行完之后,才执行当前线程后续代码");
 setFlagTest.join();
 System.out.println("线程退出");
    }

}

打印结果如下

子线程已经开启
主线程休眠3秒
子线程执行中。。。
子线程执行中。。。
修改退出标志
join() 代表让子线程执行完之后,才执行当前线程后续代码
子线程执行中。。。
子线程退出
线程退出

但是当当前线程处于阻塞时,使线程处于不可运行状态,即使主线程为该现成设置退出标记位为true
但该线程此时根本无法检测循环标志,因此也无法立即终止
代码验证如下:
注:Thread.currentThread().join();的意思是等待当前线程执行完成再执行(相当于一个死循环的逻辑)

public class BlockSetFlagTest extends Thread {

    //退出标识
    public volatile boolean exit = false;

    @Override
    public void run(){
 while (!exit){
     try {
  System.out.println("子线程阻塞之前");
  Thread.currentThread().join();
     } catch (InterruptedException e) {
  System.out.println("子线程阻塞。。。");
  e.printStackTrace();
     }
 }
 System.out.println("子线程执行完成");
    }

    public static void main(String[] args) throws InterruptedException {
 BlockSetFlagTest blockSetFlagTest = new BlockSetFlagTest();
 System.out.println("开启子线程");
 blockSetFlagTest.start();
 System.out.println("中断主线程。。。");
 sleep(3000);
 System.out.println("修改flag...");
 blockSetFlagTest.exit = true;
 System.out.println("主线程结束");


    }
}

打印结果可以看到子线程处于阻塞中,且没有打印”子线程执行完成“这句话因此可以验证上面观点

2.想要让以上线程终止(运行完成),可以在主线程里面增加一个中断,使得子线程抛出异常捕获
代码如下:

public class BlockSetFlagTest extends Thread {

    //退出标识
    public volatile boolean exit = false;

    @Override
    public void run(){
 while (!exit){
     try {
  System.out.println("子线程阻塞之前");
  Thread.currentThread().join();
     } catch (InterruptedException e) {
  System.out.println("子线程阻塞。。。");
  e.printStackTrace();
     }
 }
 System.out.println("子线程执行完成");
    }

    public static void main(String[] args) throws InterruptedException {
 BlockSetFlagTest blockSetFlagTest = new BlockSetFlagTest();
 System.out.println("开启子线程");
 blockSetFlagTest.start();
 System.out.println("中断主线程。。。");
 sleep(3000);
 System.out.println("修改flag...");
 blockSetFlagTest.exit = true;
 System.out.println("让子线程中断");
 blockSetFlagTest.interrupt();
 System.out.println("主线程结束");
    }
}

代码执行结果如下:

开启子线程
中断主线程。。。
子线程阻塞之前
修改flag...
让子线程中断
主线程结束
子线程阻塞。。。
java.lang.InterruptedException
	at java.lang.Object.wait(Native Method)
	at java.lang.Thread.join(Thread.java:1245)
	at java.lang.Thread.join(Thread.java:1319)
	at ThreadStudy.stopTread.BlockSetFlagTest.run(BlockSetFlagTest.java:16)
子线程执行完成
Process finished with exit code 0

3.废弃的线程终止方式(不推荐使用)
1> Tread.stop()
源码中已经清楚废弃这个方法
这个方法强行终止线程,是很危险的,类似于电脑突然被拔电源,而不是正常关机,产生不可预料的后果。
这个方法会强制释放子线程所有的锁,导致被保护的资源出现线程安全
这个方法调用以后,创建的子线程会抛ThreadDeath这个Error
2> Tread.suspend()
使得线程暂停
不会释放类似锁这种资源,也是很危险的
3>Tread.resume()
使得线程恢复
如果在调用resume()方法之前,没有调用suspend(),则不会起作用
suspend()和resume()必须成对出现,否则会出现死锁
4>Runtime.runFinalizersonExit()
这个方法本身就是不安全的
它可能导致终结器(finalizers)被在活跃对象上被调用,假如其他线程正在操作这个对象会有问题,而且,这个调用不是“线程安全的”,因为他设置了一个VM全局标志

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/237296.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号