java線程的中斷和同步問題的實現(xiàn)
1、自動終斷【完成】:一個線程完成執(zhí)行后(即run方法執(zhí)行完畢),不能再次運行 。
2、手動中斷:
stop( ) —— 已過時,基本不用。(不安全,就像是突然停電)
interrupt( ) ——此方法只是改變中斷狀態(tài),不會中斷一個正在運行的線程。比如:如果當(dāng)前線程是阻塞狀態(tài),那么就結(jié)束阻塞狀態(tài)
3、可通過使用一個標(biāo)志指示 run 方法退出,從而終止線程(推薦使用)
使用場景
- 點擊某個桌面應(yīng)用中的取消按鈕時;
- 某個操作超過了一定的執(zhí)行時間限制需要中止時;
- 多個線程做相同的事情,只要一個線程成功其它線程都可以取消時;
- 一組線程中的一個或多個出現(xiàn)錯誤導(dǎo)致整組都無法繼續(xù)時;
- 當(dāng)一個應(yīng)用或服務(wù)需要停止時
- interrupt( )方法說明:interrupt()方法只是改變中斷狀態(tài),不會中斷一個正在運行的線程。這一方法實際完成的是,給受阻塞的線程發(fā)出一個中斷信號,這樣受阻線程檢查到中斷標(biāo)識,就得以退出阻塞的狀態(tài)。更確切的說,如果線程被Object.wait, Thread.join和Thread.sleep三種方法之一阻塞,此時調(diào)用該線程的interrupt()方法,那么該線程將拋出一個 InterruptedException中斷異常(該線程必須事先預(yù)備好處理此異常),從而提早地終結(jié)被阻塞狀態(tài)。如果線程沒有被阻塞,這時調(diào)用 interrupt()將不起作用,直到執(zhí)行到wait(),sleep(),join()時,才馬上會拋出 InterruptedException。
線程同步問題
同步解決方案synchronized
1.在java語言中,引入了同步鎖的概念,每個對象都有一個與之關(guān)聯(lián)的內(nèi)部鎖(排他鎖),用以保證共享數(shù)據(jù)的安全性問題。
2.關(guān)鍵詞synchronized用來給某個方法或某段代碼加上一個同步鎖。
3.當(dāng)調(diào)用者調(diào)用此方法時,必須獲得這把鎖才可以調(diào)用。
4.當(dāng)某個調(diào)用者獲得這把鎖之后,其他調(diào)用者就無法獲得了。
5.當(dāng)調(diào)用結(jié)束后,調(diào)用者釋放這把鎖,此時其他調(diào)用者才可以獲得。
6.這個機制保障了某個同步方法同時只能有一個調(diào)用者
鎖定方法
public class Account { private int balance = 1000; public synchronized void qu(){ // 同步方法 if(balance>=1000){ try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } balance -= 1000; System.out.println("取了1000元,balance = " + balance); } } }
鎖定代碼塊
public class Account { private int balance = 1000; public void qu(){ System.out.println("Account.qu"); synchronized( "this" ){ // 同步塊 if(balance>=1000){ try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } balance -= 1000; System.out.println("取了1000元,balance = " + balance); } } } }
死鎖
線程同步的第二種解決方案 wait() notify()
生產(chǎn)者-消費者(producer-consumer)問題,也稱作有界緩沖區(qū)(bounded-buffer)問題,兩個線程共享一個公共的固定大小的緩沖區(qū)。其中一個是生產(chǎn)者,用于將消息放入緩沖區(qū);另外一個是消費者,用于從緩沖區(qū)中取出消息。問題出現(xiàn)在當(dāng)緩沖區(qū)已經(jīng)滿了,而此時生產(chǎn)者還想向其中放入一個新的數(shù)據(jù)項的情形,其解決方法是讓生產(chǎn)者此時進行休眠,等待消費者從緩沖區(qū)中取走了一個或者多個數(shù)據(jù)后再去喚醒它
package test06; //倉庫(有界緩沖區(qū)) class Storage{ private int count = 0; public synchronized void set(){ if(count>=5){ try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } count++; System.out.println("生產(chǎn)了一個,倉庫中有:" + count); this.notify(); } public synchronized void get(){ if(count<=0){ try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } count--; System.out.println("消費了一個,倉庫中有:" + count); this.notify(); } } //生產(chǎn)者 class Producer extends Thread{ private Storage storage; public Producer(Storage storage){ this.storage = storage; } public void run(){ for(int i=0;i<50;i++){ this.storage.set(); } } } //消費者 class Customer extends Thread{ private Storage storage; public Customer(Storage storage){ this.storage = storage; } public void run(){ for(int i=0;i<50;i++){ this.storage.get(); } } } public class Test2 { public static void main(String[] args) { Storage storage = new Storage(); Producer producer = new Producer(storage); Customer customer = new Customer(storage); customer.start(); producer.start(); } }
到此這篇關(guān)于java線程的中斷和同步問題的實現(xiàn)的文章就介紹到這了,更多相關(guān)java線程中斷和同步內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringSecurity數(shù)據(jù)庫進行認(rèn)證和授權(quán)的使用
本文主要介紹了用戶的賬號、密碼以及角色信息在數(shù)據(jù)庫中的認(rèn)證和授權(quán),文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-08-08java 使用簡單的demo實例告訴你優(yōu)化算法的強大
本篇文章介紹了,在java中使用簡單的demo實例告訴你優(yōu)化算法的強大。需要的朋友參考下2013-05-05Docker 部署 SpringBoot 項目整合 Redis 鏡像做訪問計數(shù)示例代碼
這篇文章主要介紹了Docker 部署 SpringBoot 項目整合 Redis 鏡像做訪問計數(shù)Demo,本文給大家介紹的非常詳細(xì),具有參考借鑒價值,需要的朋友可以參考下2018-01-01SpringBoot2.x 整合Spring-Session實現(xiàn)Session共享功能
這篇文章主要介紹了SpringBoot2.x 整合Spring-Session實現(xiàn)Session共享功能,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價值,需要的朋友可以參考下2019-07-07