生活随笔
收集整理的這篇文章主要介紹了
多线程安全问题1
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
1.問題的產生
原因:多個線程操作同一個共享數據。
原理:多個線程在訪問共享數據時,由于CPU的隨機性,一個線程還沒有執行完,執行權被其他線程搶走了,這個時候就有可能出現線程安全問題。
解決方式:把操作共享數據的代碼鎖起來,讓單一線程執行完畢才能執行其他的
2.解決方法【上鎖】
三種方法的測試類【測試類相同】
public class Demo {public static void main(String[] args
) {TicketRunnable ticketRunnable
= new TicketRunnable();Thread thread1
= new Thread(ticketRunnable
);Thread thread2
= new Thread(ticketRunnable
);Thread thread3
= new Thread(ticketRunnable
);thread1
.setName("1號窗口---");thread1
.start();thread2
.setName("2號窗口---");thread2
.start();thread3
.setName("3號窗口---");thread3
.start();}
}打印結果:
----------------------------------------------------------------------------------------------------
2號窗口
---賣了一張票
,還剩
2張票
3號窗口
---賣了一張票
,還剩
1張票
3號窗口
---賣了一張票
,還剩
0張票
<1>同步代碼塊
鎖對象:可以是任意對象,但是要保證唯一;
synchronized(鎖對象){
多個線程訪問共享數據的代碼
}
public class TicketRunnable implements Runnable {int ticket
= 100;@Overridepublic void run() {while (true) {synchronized (TicketRunnable.class){if (ticket
<=0){break;}else {try {Thread.sleep(100);} catch (InterruptedException e
) {e
.printStackTrace();}ticket
--;System.out
.println(Thread.currentThread().getName()+"賣了一張票,還剩" + ticket
+ "張票");}}}}
}
<2>同步方法/靜態同步方法
同步方法:一個線程執行這個方法,另一個線程就必須等待;
同步方法的鎖對象:this
public class TicketRunnable implements Runnable {private static int ticket
=100;@Overridepublic void run() {while (true) {boolean flag
= method();if(flag
){break;}}}private static synchronized boolean method() {if (ticket
<=0){return true;}else {try {Thread.sleep(100);} catch (InterruptedException e
) {e
.printStackTrace();}ticket
--;System.out
.println(Thread.currentThread().getName()+"賣了一張票,還剩" + ticket
+ "張票");return false;}}
}
<3>lock鎖手動上鎖和解鎖
ReentrantLock lock = new ReentrantLock(); //【具體子類或者實現類】創建鎖對象
//上鎖
lock.lock(); //一個線程執行到這里,其他線程就必須在這里等
//有可能產生安全問題的代碼
//解鎖
lock.unlock(); //等這個線程執行完了,其他線程才能進來執行。
public class TicketRunnable implements Runnable {private int ticket
= 100;ReentrantLock lock
= new ReentrantLock();@Overridepublic void run() {while (true) {try {lock
.lock();if (ticket
<= 0) {break;} else {Thread.sleep(100);ticket
--;System.out
.println(Thread.currentThread().getName() + "賣了一張票,還剩" + ticket
+ "張票");}} catch (Exception e
) {e
.printStackTrace();} finally {lock
.unlock();}}}
}
3.死鎖情況【面試】
產生條件:就是鎖的嵌套導致
概念:當其他線程持有對方所需要的資源,導致這些線程處理等待狀態,無法繼續執行
public class Demo1 {public static void main(String[] args
) {Object objA
= new Object();Object objB
= new Object();new Thread (() -> {while (true){synchronized (objA
){synchronized (objB
){System.out
.println("小康同學正在走路");}}}}).start();new Thread(() -> {while (true){synchronized (objB
){synchronized (objA
){System.out
.println("小微同學正在走路");}}}}).start();}
}打印結果:【程序不結束,且也無法向前運行】
----------------------------------------------------------------------------------------------------
小康同學正在走路
小康同學正在走路
小康同學正在走路
小康同學正在走路
小康同學正在走路
結果分析:
正常情況:小康走完objA和objB,A,B鎖正常開閉;
異常情況:小康走過objA,A鎖關閉,此時小薇同學走過objB,B鎖關閉,次數A,B鎖都關閉,導致死鎖。
總結
以上是生活随笔為你收集整理的多线程安全问题1的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。