多线程之synchronized
java的堆中信息是共享的,線程是把會堆中信息拷貝,對副本進行操作,操作完再同步堆中的信息,而堆中的信息可能被b線程修改了,a線程的副本還是未修改前的,此時就引發多并發問題。解決多并發的問題就是通過枷鎖,使原先多個線程并行執行程序轉為多個線程串行執行程序。
一個對象不管多少方法用synchronized修飾,都只擁有一把鎖.
相關概念:
監視器
監視器可以看做是經過特殊布置的建筑,這個建筑有一個特殊的房間,該房間通常包含一些數據和代碼,但是一次只能一個消費者(thread)使用此房間,
當一個消費者(線程)使用了這個房間,首先他必須到一個大廳(Entry Set)等待,調度程序將基于某些標準(e.g. FIFO)將從大廳中選擇一個消費者(線程),進入特殊房間,如果這個線程因為某些原因被“掛起”,它將被調度程序安排到“等待房間”,并且一段時間之后會被重新分配到特殊房間,按照上面的線路,這個建筑物包含三個房間,分別是“特殊房間”、“大廳”以及“等待房間”。
簡單來說,監視器用來監視線程進入這個特別房間,他確保同一時間只能有一個線程可以訪問特殊房間中的數據和代碼。
synchronized是一個重量級和重入鎖,當一個線程持有鎖時,這個線程再次獲取相同的鎖,是不用等待,可以直接獲取,synchronized鎖住的代碼塊,只有由持有鎖的線程才能訪問。
相關api簡介:
Thread
Thread(Runnable target) 構造一個新線程,線程啟動會調用target的run方法.
Object
notify()
喚醒在監視器里面的一個等待線程
wait()
? 讓當前線程等待
例;
請編寫2個線程,線程1順序輸出1,3,5,……, 99 等奇數,每個數 一 。
線程2順序輸出2,4,6……100等偶數,每個數 一 。
最終的結果要求是輸出為 自然順序:1,2,3,4,……99,100。
public class TestLock2 implements Runnable {private int num;private int initNum;public TestLock2(int num, int initNum) {this.num = num;this.initNum = initNum;}@Overridepublic void run() {synchronized (this) {while (initNum < num) {this.notify();System.out.println(Thread.currentThread().getName() + ":" + initNum);initNum++;try {this.wait();} catch (InterruptedException e) {e.printStackTrace();}}}}public static void main(String[] args) {//打印一百個數,兩個線程個循環50次,兩個都是用testLock2這個實例構造,testLock2里面的全局變量是共享的TestLock2 testLock2 = new TestLock2(51, 1);Thread thread1 = new Thread(testLock2);thread1.setName("線程1");Thread thread2 = new Thread(testLock2);thread2.setName("線程2");thread1.start();try {thread1.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}thread2.start();}}
?
轉載于:https://www.cnblogs.com/thomas-seven/p/9002791.html
總結
以上是生活随笔為你收集整理的多线程之synchronized的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Oracle问题
- 下一篇: Postman接口测试之POST、GET