亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

java筆記六:線程間的協調

2019-11-17 03:27:30
字體:
來源:轉載
供稿:網友

  昨天重新學習了java多線程的使用,多線程的難點就在線程之間的協調。在《操作系統》一課中,我們學習了進程,其實多線程和多進程一樣,都會涉及到多個進程或者線程對某一資源共享訪問的問題,當多個線程都需要修改這個資源的時候就會出現線程安全問題。

  比如說在銀行開個賬戶會有一個存折和一張卡,如果某一天同一時間丈夫拿著存折去柜臺取錢,而妻子拿著銀行卡去ATM取錢。當丈夫查詢余額里面有3000元,正準備取2000元,這時候妻子也到ATM里面查詢也有3000,也取2000元。其實銀行不可能讓我們這么做,如果這樣的話那我們天天取錢去了,還搞什么工作啊。其實在丈夫查詢的時候已經對該賬號上了鎖,另外的銀行卡要取錢的話必須等待該鎖被釋放。下面用一個程序模擬這個例子:


 1 package com.sync;
 2
 3 public class TestSync2 implements Runnable{
 4     public BankCard bc = new BankCard();
 5     public static void main(String[] args) {
 6         TestSync2 test = new TestSync2();
 7         Thread wife = new Thread(test);
 8         Thread husband = new Thread(test); 
 9         wife.setName("wife");
10         husband.setName("husband");
11         wife.start();
12         husband.start();
13     }
14     public void run() {
15         bc.getMoney(Thread.currentThread().getName(), 2000);
16     }
17 }
18 class BankCard{
19     PRivate static int money = 3000;//模擬賬戶余額
20     public synchronized void getMoney(String name,int m){
21         //synchronized(this){
22             try {
23                 Thread.sleep(1);
24             } catch (InterruptedException e) {
25                 e.printStackTrace();
26             }
27             if(money > m){
28                 System.out.println(name+"取走了"+m+"元");
29                 money = money - m;
30             }else{
31                 System.out.println("對不起,您的余額不足!");
32             }
33         //}
34     }
35 }

  

  上面的例子如果在getMoney()方法上面不加synchronized關鍵字的話,輸出結果為:

wife取走了2000元
husband取走了2000元

  而加上synchronized后,輸出結果為:

wife取走了2000元
對不起,您的余額不足!

  上面兩種情況說明,如果多個線程同時訪問某個資源,而不給該資源枷鎖的話,就會出現問題。而加上synchronized關鍵字后就可以避免這種錯誤發生了。它能夠保證只有一個線程能夠訪問getMoney()這個方法,其他藥訪問該方法的線程必須等待。

鎖住某個資源可以用synchronized關鍵字來修飾一個方法或者同步代碼塊,這樣能保證同一時間只能由一個線程訪問該資源。

   ?、?、當兩個并發線程訪問同一個對象object中的這個synchronized(this)同步代碼塊時,一個時間內只能有一個線程得到執行。另一個線程必須等待當前線程執行完這個代碼塊以后才能執行該代碼塊。

      ②、然而,當一個線程訪問object的一個synchronized(this)同步代碼塊時,另一個線程仍然可以訪問該object中的非synchronized(this)同步代碼塊。

        ③、尤其關鍵的是,當一個線程訪問object的一個synchronized(this)同步代碼塊時,其他線程對object中所有其它synchronized(this)同步代碼塊的訪問將被阻塞。

  我們都知道,操作系統中多個進程之間如果不進行協調就很容易出現死鎖的情況,死鎖的四個條件:互斥、占有等待、非剝奪、循環等待。我們只要破壞其中一個條件就能避免死鎖發生。線程之間也容易出現死鎖,下面這個例子就演示了死鎖的情況:


 1 package com.sync;
 2
 3 import com.thread.SleepTest;
 4
 5
 6 public class TestDeadLock implements Runnable{
 7     int flag = 1;
 8     static Object o1 = new Object();
 9     static Object o2 = new Object();
10     public void run() {
11         System.out.println(flag);
12         if(flag == 1){
13             synchronized (o1) {
14                 try {
15                     Thread.sleep(1000);
16                 } catch (InterruptedException e) {
17                     e.printStackTrace();
18                 }
19                 synchronized (o2) {
20                     System.out.println("1");
21                 }
22             }
23         }
24         if(flag == 0){
25             synchronized (o2) {//鎖住某個對象,相當于占有該對象不讓其他人使用
26                 try {
27                     Thread.sleep(1000);
28                 } catch (InterruptedException e) {
29                     e.printStackTrace();
30                 }
31                 synchronized (o1) {
32                     System.out.println("0");
33                 }
34             }
35         }
36     }
37     public static void main(String[] args) {
38         TestDeadLock t1 = new TestDeadLock();
39         TestDeadLock t2 = new TestDeadLock();
40         t1.flag = 1;
41         t2.flag = 0;
42         new Thread(t1).start();
43         new Thread(t2).start();
44     }
45 }

  運行程序輸出1    0后就進入死鎖狀態,該程序永遠也不會停止,因為兩個線程同時處于等待狀態。線程t1鎖住了o1對象,等待o2對象,而線程t2鎖住o2等待o2對象,誰也不讓誰,這就進入了一個循環占有等待的情況了,死鎖也就出現了。

  所以,如果多個線程如果不進行協調的話很容易出現死鎖的問題。操作系統中使用進程調度來協調各個進程,那么java重如何對各個線程進行協調呢?

  java中主要使用Object類中的wait()、notify()、notifyAll()方法來協調各個線程。典型的例子有哲學家吃飯問題、生產者和消費者問題、理發師問題。下面一個用一個例子來演示生產者和消費者問題。

  問題描述:生產者負責做饅頭,做好饅頭后放進指定的簍子里面,消費者消費該簍子里面的饅頭。簍子里只能裝一定量的饅頭,滿了以后生產者必須進入等待狀態,消費者吃完饅頭后也必須進入等待狀態。


 1 package com.sync;
 2
 3 public class ProductAndConsumer {
 4     public static void main(String[] args) {
 5         Basket b = new Basket();
 6         Product p = new Product(b);
 7         Consumer c = new Consumer(b);
 8         new Thread(p).start();
 9         new Thread(c).start();
10     }
11 }
12
13 class ManTou{
14     int id;
15     public ManTou(int id) {
16         this.id = id;
17     }
18     @Override
19     public String toString() {
20         return "ManTou"+id;
21     }
22 }
23
24 //裝饅頭的籃子
25 class Basket{
26     int index = 0; //相當于棧頂指針
27     ManTou[] manTous = new ManTou[6];
28     //往籃子里面放饅頭
29     public synchronized void push(ManTou m){
30         while(index == manTous.length){
31             try {
32                 this.wait();
33             } catch (InterruptedException e) {
34                 e.printStackTrace();
35             }
36         }
37         this.notify();
38         manTous[index] = m;
39         index++;
40     }
41     //往籃子里面取饅頭
42     public synchronized ManTou pop(){
43         while(index == 0){
44             try {
45                 this.wait();
46             } catch (InterruptedException e) {
47                 e.printStackTrace();
48             }
49         }
50         this.notify();
51         index--;
52         return manTous[index];
53     }
54 }
55 //生產者
56 class Product implements Runnable{
57     Basket basket;
58     public Product(Basket basket) {
59         this.basket = basket;
60     }
61     public void run() {
62         for (int i = 0; i < 20; i++) {
63             ManTou m = new ManTou(i);
64             basket.push(m);
65             System.out.println("生產了"+m);
66             try {
67                 Thread.sleep(1);
68             } catch (InterruptedException e) {
69                 e.printStackTrace();
70             }
71            
72         }
73     }
74 }
75
76 //消費者
77 class Consumer implements Runnable{
78     Basket basket;
79     public Consumer(Basket basket) {
80         this.basket = basket;
81     }
82     public void run() {
83         for (int i = 0; i < 20; i++) {
84             ManTou m = basket.pop();
85             System.out.println("消費了"+m);
86             try {
87                 Thread.sleep((int)(Math.random()*1000));
88             } catch (InterruptedException e) {
89                 e.printStackTrace();
90             }
91         }
92     }
93 }

  wait()、notify()、notifyAll()方法的作用:

    wait():導致當前的線程等待,直到其他線程調用此對象的 notify() 方法或 notifyAll() 方法。

    notify():喚醒在此對象監視器上等待的單個線程。

    notifyAll():喚醒在此對象監視器上等待的所有線程。

  wait()與sleep()的區別:

    兩個方法的共同點就是讓當前線程進入等待狀態。

    不同點:

    wait()之后,鎖就不歸我所有了,必須等醒過來后才能擁有該鎖,并且必須要有人喚醒它才會醒過來
    sleep()不同,鎖還是歸我所有,一段時間后會自動醒過來


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产专区欧美专区| 亚洲成人三级在线| 国产精品一区二区av影院萌芽| 日韩禁在线播放| 成人精品久久久| 在线电影欧美日韩一区二区私密| 久久久综合免费视频| 精品亚洲aⅴ在线观看| 国产午夜精品一区理论片飘花| 成人激情综合网| 久久亚洲成人精品| 91爱视频在线| 一区二区三区动漫| 国产亚洲精品久久久久久| 亚洲精品二三区| 免费不卡欧美自拍视频| 国产精品入口尤物| 国产成人精品亚洲精品| 日韩在线视频观看正片免费网站| 欧美黑人性生活视频| 亚洲最新av在线| 日韩av最新在线观看| 91精品久久久久久久久| 热99精品只有里视频精品| 日韩av影院在线观看| 亚洲护士老师的毛茸茸最新章节| 国产精品扒开腿做爽爽爽视频| 成人网址在线观看| 亚洲国产精品嫩草影院久久| 日产精品99久久久久久| 国产成人精品优优av| 国产精品99久久久久久人| 欧美电影免费在线观看| 国产精品亚洲一区二区三区| 大量国产精品视频| 久久久久久香蕉网| 国产精品美女久久久免费| 超碰日本道色综合久久综合| 国产精品偷伦视频免费观看国产| 91美女福利视频高清| 国模吧一区二区三区| 国产成人精品久久亚洲高清不卡| 亚洲精品成人免费| 欧美性xxxx| 亚洲一区中文字幕| 欧美床上激情在线观看| 国产精品三级久久久久久电影| 国产精品永久免费观看| 国产美女搞久久| 国产一区二区三区视频在线观看| 亚洲精品国产综合区久久久久久久| 一本一本久久a久久精品综合小说| 欧美在线视频a| zzjj国产精品一区二区| 日韩免费av片在线观看| 91超碰中文字幕久久精品| 国产精品视频免费在线| 国产精品欧美激情| 国产精品久久久久久中文字| 欧美激情精品久久久久久免费印度| 91极品视频在线| 国产精品久久97| 久久久久九九九九| 97视频免费在线观看| 欧美性猛交xxxx免费看| 国产精品久久久久久久9999| 欧美高清视频一区二区| 97免费在线视频| 国产美女久久久| 亚洲色图17p| 国产视频在线一区二区| 毛片精品免费在线观看| 中日韩美女免费视频网站在线观看| 精品日韩中文字幕| 亚洲天堂日韩电影| 中文字幕精品av| 久久久极品av| 欧美在线一级va免费观看| 欧美性极品xxxx做受| 91国在线精品国内播放| 伊人成人开心激情综合网| 国产精品高清网站| 国产精品h片在线播放| 国内精品久久久久久久久| 国产成人精品久久亚洲高清不卡| 最好看的2019年中文视频| 亚洲精品黄网在线观看| 亚洲欧美日韩综合| 日韩免费在线免费观看| 日韩电影免费观看中文字幕| 成人国产精品色哟哟| 亚洲欧美精品在线| 久久精品视频导航| 中文字幕国产亚洲| 国产精品视频午夜| 国产精品视频久| 91丝袜美腿美女视频网站| 91高清视频免费| 成人免费自拍视频| 亚洲欧美日韩国产精品| 热久久视久久精品18亚洲精品| 国产成人97精品免费看片| 久久久久久久久久国产| 成人性生交大片免费观看嘿嘿视频| 亚洲福利视频二区| 国产精品高潮粉嫩av| 日韩av123| 国产在线久久久| 色偷偷91综合久久噜噜| 欧美夫妻性生活xx| 日韩精品久久久久久久玫瑰园| 亚洲一区二区免费在线| 日韩网站免费观看高清| 色www亚洲国产张柏芝| 欧美第一淫aaasss性| 在线视频国产日韩| 亚洲在线免费观看| 丝袜一区二区三区| 2024亚洲男人天堂| 国产精品久久久久久久久免费看| 亚洲视频日韩精品| 精品国产拍在线观看| 91丨九色丨国产在线| 国产日韩精品综合网站| 国产精品狠色婷| 国产精品久久久久秋霞鲁丝| 国产精品嫩草影院久久久| 久久成人一区二区| 亚洲嫩模很污视频| 日韩视频在线免费观看| 最近2019中文字幕一页二页| 国内精品视频在线| 日韩成人在线视频网站| 久久久久国产精品免费网站| 精品成人在线视频| 欧美性视频在线| 欧美日韩久久久久| 欧美日韩一区二区免费视频| 欧洲s码亚洲m码精品一区| 最近2019中文字幕第三页视频| 欧美乱妇40p| 一区二区三区视频观看| 国模吧一区二区| 国产精品wwww| 97超级碰碰人国产在线观看| 欧美日本精品在线| 久久久91精品| 欧美电影电视剧在线观看| 国产精品免费久久久| 国产一区二区日韩| 美女撒尿一区二区三区| 色诱女教师一区二区三区| 久久久精品中文字幕| 国产精品三级美女白浆呻吟| 亚洲美女av电影| 亚洲国产精品小视频| 色婷婷av一区二区三区久久| 午夜剧场成人观在线视频免费观看| 亚洲精品自拍偷拍| 日韩欧美国产高清91| 亚洲免费电影在线观看| 91精品国产91久久久久福利| 91精品国产综合久久久久久久久| 日韩视频永久免费观看|