让你学会与理解Java的线程与并发(三,设计二阶段终止与常见方法)

Posted 韶光不负

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了让你学会与理解Java的线程与并发(三,设计二阶段终止与常见方法)相关的知识,希望对你有一定的参考价值。

创建运行与常见方法https://blog.csdn.net/weixin_47514459/article/details/121385539https://blog.csdn.net/weixin_47514459/article/details/121385539

此篇文章为上链接的下文,因为线程常见方法太多,全部书写在一篇文章当中感觉太拥挤了,所以小编就分为二篇文章方便大家观看!

目录

设计二阶段终止

二阶段终止模式(Two Phase Terminatin):

应用场景

实现流程图

实现代码

 打断park线程

 interrupt()方法打断park状态,让线程向下运行

park线程的特点 

停止线程的错误思路?

剩余常见方法 

过时方法(不推荐使用方法)

不推荐使用原因

守护线程


设计二阶段终止

二阶段终止模式(Two Phase Terminatin):

在线程1中如何“优雅”终止线程2。(优雅指的是给线程2一个做善后工作,然后自己停止自己 !)

应用场景

比如说:想创建一个线程实现定时监控各个线程的情况!当突然不想监控了就需要程序终止。

实现流程图

实现代码

package com.luo_sf.map;

public class ThieadText 
    public static void main (String[] args) throws InterruptedException 
        Monitoring tp = new Monitoring();
        tp.start();
        Thread.sleep(3000);
        tp.stop();

    


//监控类
class Monitoring
    //创建一个监控线程
    private Thread monitor;

    //启动线程方法
    public void start()
        monitor = new Thread(()->
            //设置循环实现每隔一段时间监控
            while (true) 
                //获取被监控的线程
                Thread current = Thread.currentThread();
                //查看该线程是否被打断
                if(current.isInterrupted())
                    //退出循环
                    System.out.println("该线程被打断,料理后事");
                    break;
                
                try 
                    Thread.sleep(1000);
                    System.out.println("实现监控");
                 catch (InterruptedException e) 
                    e.printStackTrace();
                    //当在睡眠时被打断,修改打断标记,实现退出循环
                    current.interrupt();
                
            

        ,"monitor");
    monitor.start();
    

    //关闭线程方法
    public void stop()
        monitor.interrupt();
    


现象:

 打断park线程

park()方法,并不是Thread中的方法,而是锁支持类LockSupport中的方法(LockSupport.park())

作用:让当前线程停止(停止在哪,不动了)。

public class ThieadText 
    public static void main (String[] args) throws InterruptedException 
        Thread t = new Thread(()->
            System.out.println("创建了一个线程");
            // LockSupport.park()方法让线程停止
            LockSupport.park();
            System.out.println("线程停止了");
            System.out.println("打断状体为:"+Thread.currentThread().isInterrupted());
        ) ;
        //启动线程
        t.start();
    

 interrupt()方法打断park状态,让线程向下运行

public class ThieadText 
    public static void main (String[] args) throws InterruptedException 
        Thread t = new Thread(()->
            System.out.println("创建了一个线程");
            // LockSupport.park()方法让线程停止
            LockSupport.park();
            System.out.println("线程停止了");
            System.out.println("打断状体为:"+Thread.currentThread().isInterrupted());
        ) ;
        //启动线程
        t.start();

        Thread.sleep(1000);

        //打断park,让线程向下运行
        t.interrupt();
    

park线程的特点 

当你打断一次park线程后,打断标记为true时,在执行park,就不会起到第一次是的停止作用。

当打断标记为false时,park才能起作用。

package com.luo_sf.map;

import java.util.concurrent.locks.LockSupport;

public class ThieadText 
    public static void main (String[] args) throws InterruptedException 
        Thread t = new Thread(()->
            System.out.println("创建了一个线程");
            // LockSupport.park()方法让线程停止
            LockSupport.park();
            System.out.println("线程停止了");
            //Thread.currentThread()方法,获取当前打断标记状态后,标记进行反转(true <-> false )
            System.out.println("打断状体为:"+Thread.currentThread());
            LockSupport.park();
            
            System.out.println("线程停止了");
        ) ;
        //启动线程
        t.start();

        Thread.sleep(1000);

        //打断park,让线程向下运行
        t.interrupt();
    


停止线程的错误思路?

1,使用线程对象中的stop()方法停止线程。

stop()方法会真正的杀死线程,如果stop时该线程锁住了共享共享资源,那么当它死后就再也没有机会是放锁,其他线程将无法获取资源,运行出现错误!)

2,使用System.exit()停止线程(被废弃了)。

(当你想停止这一个线程,但使用System.exit()会停止整个程序

剩余常见方法 

过时方法(不推荐使用方法)

stop()强制停止线程运行
suspend()挂起(暂停)线程
resume()恢复线程运行

不推荐使用原因

会破坏同步代码块,造成对象的锁得不到释放,线程死锁,程序出现问题。stop()方法使用二阶段终止模式代替。

守护线程

默认情况下,Java进程需要等待所以的线程运行结束,才会结束,有一种特殊的线程叫守护线程,只要其他非守护线程结束了,就算守护线程的代码没有执行完,守护线程也会被强制结束。

package com.luo_sf.map;

import java.util.concurrent.locks.LockSupport;

public class ThieadText 
    public static void main (String[] args) throws InterruptedException 
        Thread t = new Thread(()->
            System.out.println("创建了一个线程");
            while (true)
                System.out.println("进入循环");
                if (Thread.currentThread().isInterrupted())
                    System.out.println("结束循环");
                    break;
                
            

        ) ;
        //将t线程改为守护线程
        t.setDaemon(true);
        //启动线程
        t.start();

        Thread.sleep(1);

        System.out.println("主线程结束了");
    



当主线程结束会,守护线程并不会马上结束。

以上是关于让你学会与理解Java的线程与并发(三,设计二阶段终止与常见方法)的主要内容,如果未能解决你的问题,请参考以下文章

让你学会与理解Java的线程与并发(二,创建运行与常见方法)

让你学会与理解Java的线程与并发(一,线程与进程,并发)

让你学会与理解Java的线程与并发(四,线程状态)

12 认识进程与线程 (进阶)

并发编程与技术内幕:线程池深入理解

浅剖Java进程与线程