偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

Java LockSupport與線程中斷

開發(fā) 前端
LockSupport類使用了一種名為Permit(許可)的概念來做到阻塞和喚醒線程的功能, 每個(gè)線程都有一個(gè)許可(permit),permit只有兩個(gè)值1和零,默認(rèn)是零。

什么是中斷?

首先

一個(gè)線程不應(yīng)該由其他線程來強(qiáng)制中斷或停止,而是應(yīng)該由線程自己自行停止。所以,Thread.stop, Thread.suspend, Thread.resume 都已經(jīng)被廢棄了。

其次

在Java中沒有辦法立即停止一條線程,然而停止線程卻顯得尤為重要,如取消一個(gè)耗時(shí)操作。因此,Java提供了一種用于停止線程的機(jī)制——中斷。

中斷只是一種協(xié)作機(jī)制,Java沒有給中斷增加任何語法,中斷的過程完全需要程序員自己實(shí)現(xiàn)。

若要中斷一個(gè)線程,你需要手動(dòng)調(diào)用該線程的interrupt方法,該方法也僅僅是將線程對(duì)象的中斷標(biāo)識(shí)設(shè)成true;

接著你需要自己寫代碼不斷地檢測(cè)當(dāng)前線程的標(biāo)識(shí)位,如果為true,表示別的線程要求這條線程中斷,

此時(shí)究竟該做什么需要你自己寫代碼實(shí)現(xiàn)。

每個(gè)線程對(duì)象中都有一個(gè)標(biāo)識(shí),用于表示線程是否被中斷;該標(biāo)識(shí)位為true表示中斷,為false表示未中斷;通過調(diào)用線程對(duì)象的interrupt方法將該線程的標(biāo)識(shí)位設(shè)為true;可以在別的線程中調(diào)用,也可以在自己的線程中調(diào)用。

public void interrupt()

實(shí)例方法,interrupt()僅僅是設(shè)置線程的中斷狀態(tài)為true,不會(huì)停止線程

public static boolean interrupted()


靜態(tài)方法,Thread.interrupted();

判斷線程是否被中斷,并清除當(dāng)前中斷狀態(tài)

這個(gè)方法做了兩件事:

1 返回當(dāng)前線程的中斷狀態(tài)

2 將當(dāng)前線程的中斷狀態(tài)設(shè)為false

public boolean isInterrupted()

實(shí)例方法,

判斷當(dāng)前線程是否被中斷(通過檢查中斷標(biāo)志位)

如何使用中斷標(biāo)識(shí)停止線程?

三種方式

  • 通過一個(gè)volatile變量實(shí)現(xiàn)
package com.atguigu.juc.senior.test;

import java.util.concurrent.TimeUnit;


public class InterruptDemo{
	private static volatile boolean isStop = false;
	public static void main(String[] args){
        new Thread(() -> {
            while(true) {
                if(isStop) {
                    break;
                }
                System.out.println("-------hello interrupt");
            }
        },"t1").start();

        //暫停幾秒鐘線程
        try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); }
        isStop = true;
    }

}
  • 通過AtomicBoolean
package com.zzyy.study.test;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;


public class StopThreadDemo{
	
    private final static AtomicBoolean atomicBoolean = new AtomicBoolean(true);

	 public static void main(String[] args) {
        Thread t1 = new Thread(() -> {
            while(atomicBoolean.get()) {
                try { TimeUnit.MILLISECONDS.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); }
                System.out.println("-----hello");
            }
        }, "t1");
        t1.start();

        try { TimeUnit.SECONDS.sleep(3); } catch (InterruptedException e) { e.printStackTrace(); }

        atomicBoolean.set(false);
    }
}
  • 通過Thread類自帶的中斷api方法實(shí)現(xiàn)

當(dāng)前線程的中斷標(biāo)識(shí)為true,是不是就立刻停止?

具體來說,當(dāng)對(duì)一個(gè)線程,調(diào)用 interrupt() 時(shí):

① 如果線程處于正?;顒?dòng)狀態(tài),那么會(huì)將該線程的中斷標(biāo)志設(shè)置為 true,僅此而已。

被設(shè)置中斷標(biāo)志的線程將繼續(xù)正常運(yùn)行,不受影響。所以, interrupt() 并不能真正的中斷線程,需要被調(diào)用的線程自己進(jìn)行配合才行。

② 如果線程處于被阻塞狀態(tài)(例如處于sleep, wait, join 等狀態(tài)),在別的線程中調(diào)用當(dāng)前線程對(duì)象的interrupt方法,那么線程將立即退出被阻塞狀態(tài),并拋出一個(gè)InterruptedException異常。

需要注意的是Sleep方法拋出InterruptedException異常后,中斷標(biāo)識(shí)也被清空置為false, 需要在catch中再次調(diào)用 .interrupt( )方法進(jìn)行中斷,否則就會(huì)導(dǎo)致無線循環(huán)。

LockSupport是什么

LockSupport是用來創(chuàng)建鎖和其他同步類的基本線程阻塞原語。

LockSupport中的park() 和 unpark() 的作用分別是阻塞線程和解除阻塞線程

3種讓線程等待和喚醒的方法

  • 方式1:使用Object中的wait()方法讓線程等待,使用Object中的notify()方法喚醒線程
  • 方式2:使用JUC包中Condition的await()方法讓線程等待,使用signal()方法喚醒線程
  • 方式3:LockSupport類可以阻塞當(dāng)前線程以及喚醒指定被阻塞的線程

Object類中的wait和notify方法實(shí)現(xiàn)線程等待和喚醒

static Object objectLock = new Object();

	public static void syncWaitNotify() {
        new Thread(() -> {
            //暫停幾秒鐘線程
            try { TimeUnit.SECONDS.sleep(3); } catch (InterruptedException e) { e.printStackTrace(); }
            synchronized (objectLock){
                System.out.println(Thread.currentThread().getName()+"\t"+"---come in");
                try {
                    objectLock.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName()+"\t"+"---被喚醒");
            }
        },"t1").start();

        //暫停幾秒鐘線程
        try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); }

        new Thread(() -> {
            synchronized (objectLock){
                objectLock.notify();
                System.out.println(Thread.currentThread().getName()+"\t"+"---發(fā)出通知");
            }
        },"t2").start();
    }
  • wait和notify方法必須要在同步塊或者方法里面,且成對(duì)出現(xiàn)使用
  • 先wait后notify才OK

Condition接口中的await后signal方法實(shí)現(xiàn)線程的等待和喚醒

public static void lockAwaitSignal() {
        new Thread(() -> {
            //暫停幾秒鐘線程
            try { TimeUnit.SECONDS.sleep(3); } catch (InterruptedException e) { 
                e.printStackTrace(); }
            lock.lock();
            try{
                System.out.println(Thread.currentThread().getName()+"\t"+"---come in");
                condition.await();
                System.out.println(Thread.currentThread().getName()+"\t"+"---被喚醒");
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        },"t1").start();

        new Thread(() -> {
            lock.lock();
            try{
                condition.signal();
                System.out.println(Thread.currentThread().getName()+"\t"+"---發(fā)出通知");
            }finally {
                lock.unlock();
            }
        },"t2").start();
    }
  • Condtion中的線程等待和喚醒方法之前,需要先獲取鎖
  • 一定要先await后signal,不要反了

總結(jié):Object和Condition使用的限制條件

  • 線程先要獲得并持有鎖,必須在鎖塊(synchronized或lock)中。
  • 必須要先等待后喚醒,線程才能夠被喚醒。

LockSupport類中的park等待和unpark喚醒

是什么

LockSupport是用來創(chuàng)建鎖和其他同步類的基本線程阻塞原語。

LockSupport類使用了一種名為Permit(許可)的概念來做到阻塞和喚醒線程的功能, 每個(gè)線程都有一個(gè)許可(permit),permit只有兩個(gè)值1和零,默認(rèn)是零。可以把許可看成是一種(0,1)信號(hào)量(Semaphore),但與 Semaphore 不同的是,許可的累加上限是1。

主要方法

阻塞 park() /park(Object blocker) 阻塞當(dāng)前線程/阻塞傳入的具體線程

喚醒 unpark(Thread thread) 喚醒處于阻塞狀態(tài)的指定線程

示例

public static void main(String[] args) {
        Thread t1 = new Thread(() -> {
            System.out.println(Thread.currentThread().getName() + "\t" + "---come in");
            LockSupport.park();
            LockSupport.park();
            System.out.println(Thread.currentThread().getName() + "\t" + "---被喚醒");
        }, "t1");
        t1.start();

        new Thread(() -> {
            LockSupport.unpark(t1);
            try { TimeUnit.SECONDS.sleep(3); } catch (InterruptedException e) { e.printStackTrace(); }
            LockSupport.unpark(t1);
            System.out.println(Thread.currentThread().getName()+"\t"+"---發(fā)出通知");
        },"t2").start();
    }
  • 無鎖塊要求
  • 之前錯(cuò)誤的先喚醒后等待,LockSupport照樣支持
責(zé)任編輯:武曉燕 來源: 今日頭條
相關(guān)推薦

2021-01-11 12:53:28

線程Java管理

2009-04-23 09:07:03

JAVA終端線程

2025-06-24 08:25:00

Java并發(fā)編程線程

2017-06-04 16:24:27

線程線程池中斷

2015-08-03 09:54:26

Java線程Java

2020-12-08 06:23:05

LockSupport線程工具

2025-01-14 10:09:43

硬中斷Linux系統(tǒng)

2015-09-07 14:08:32

Java編程異步事件

2012-04-16 10:12:54

Java線程

2024-09-26 10:51:51

2022-05-26 08:31:41

線程Java線程與進(jìn)程

2023-05-12 14:14:00

Java線程中斷

2010-03-16 17:16:38

Java多線程

2017-05-04 16:33:58

Java線程池實(shí)踐

2022-04-18 07:36:37

TimeUnit線程休眠

2021-12-11 19:00:54

Java中斷機(jī)制

2021-07-30 19:44:51

AndroidJava線程

2025-06-06 02:00:00

2022-11-18 09:03:12

線程順序打印

2021-04-20 09:26:40

Cortex M架構(gòu)Cortex A架構(gòu)STM32系列
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)