スレッド間のJava学習通信(2つのスレッド)

同じプロセスのリソースで複数のスレッドが、異なるタスク:スレッド間の通信

演習1:デュアルスレッド化スレッドの安全性の問題が発生し、場所を追加するために同期コードを考えて、同期を使用することが必要である
要件を:銀行は口座にお金節約、お金を節約するためにアカウント誰を表示するために、どのくらいの預金
分析:
同じ銀行口座を操作する
二つの異なる操作を、メモリは、ディスプレイは、
二つの動作を同時に行うことができること

コード:

1  クラスバンク
 2  {
 3。      文字列名; // 名前保存
4。     INTのAMOUNT;
 5      
。6      // 操作がとら又は預金バンクすべきかどうか
。7      ボイド PUT(文字列名、int型AMOUNT)
 。8      {
 9          この .nameの= 名前;
 10          この .amount = AMOUNT;
 11      }
 12である     
13である     ボイドテイク()
 14      {
 15          のSystem.out.println(この .nameの+ "---" + この.amount);
 16     }
 17  }
 18  // 定義オブジェクトは、Runnableをを実現スレッドのタスクを設け
19の。 クラス入力を実装Runnableを
 20であり 、{
 21である     プライベート・バンクB;
 22である     // 保存コンストラクタリソースを確保するために使用され、同一のディスプレイ
23は     公衆入力(バンクB)
 24      {
 25           = .B B;
 26である     }
 27      公共 ボイドRUN()
 28      {
 29          INT X = 0 ;
 30          ながら、真の31である         {
 32             IF(X == 0 33である             {
 34である                 ( "ジョー・スミス"、100)b.put;
 35              }
 36              
37 [              {
 38であり                 ; b.put( "リシ"、200である)
 39              }
 40              // 0と1の間スイッチングが上昇2残りの部分に使用することができる
41は              X =(X + 1)2%;
 42れる         }
 43である     }
 44である }
 45  
46である // 定義オブジェクトは、タスクスレッド設定のRunnableを実装し
47  クラスに出力を実装Runnableを
 48  {
 49      のプライベート・バンクB;
 50     // 使用コンストラクタ保証保存と同じリソース表示
51される     パブリック出力(バンクB)
 52は     、{
 53であり、         この .B = B;
 54である     }
 55      公共 ボイドRUN()
 56は     、{
 57は         、一方真の58          {
 59              b.take( );
 60          }
 61である     }
 62である }
 63であり、 
64  クラスThreadDemo
 65  {
 66      公共 静的 ボイドメイン(文字列[]引数)
 67      {
68          // 同一资源
69          バンクB = 銀行();
70          
71          =に入力新しい入力(B)。
72          アウト=出力新しい出力(B);
73          
74          //
 75          スレッドT1は= 新しいスレッドを(で)。
76          スレッドT2 = 新しいスレッド(アウト)。
77          
78          t1.start()。
79          t2.start()。
80      }
 81 }

結果:

 

 

なぜ、スレッドセーフ表示されますか?

分析:

 

 ソリューション:追加同期(同期)、どのような位置に追加する同期

同期ロック原理を追加:コードが共有データ上で動作があり、同じ同期ロックの対象(同期のためのロック同期方法、そのような物体(本))

 

コード:

 1 class Bank
 2 {
 3     String name;//存钱人名
 4     int amount;
 5     
 6     //同步方法的同步锁为,此类的对象(this)
 7     synchronized void put(String name,int amount)
 8     {
 9         this.name=name;
10         this.amount=amount;
11     }
12     
13     synchronized void take()
14     {
15         System.out.println(this.name+"---"+this.amount);
16     }
17 }

结果出现的效果与预想结果不同,预想结果是存一笔,显示一笔

 

 

结果分析:

 

 接下来,想法是:在t1中执行完成后就让t2执行

具体做法:

1、使用一个共享数据(flag)记录t1是否已执行

2、已执行就让t1等待(原因:防止t1再次获取CPU执行权),让t2执行

3、t2执行完成,t2等待,把t1设置成未执行状态(让t1获取CPU执行资格)

 1 class Bank
 2 {
 3     private String name;
 4     private int amount;
 5     private boolean flag=false;
 6     
 7     synchronized void put(String name,int amount)
 8     {
 9         //1、判断线程是否已执行,防止t1线程继续获取CUP执行权
10         if(flag)
11             try{this.wait();}catch(InterruptedException e){}//wait()方法,将线程存放在阻塞线程池中,释放CUP执行权和释放同步锁
12             
13         this.name=name;
14         this.amount=amount;
15         //已执行赋值
16         this.flag = true;
17         //唤醒阻塞线程池中的第一个线程,获取CUP执行资格
18         this.notify();
19     }
20     
21     synchronized void take()
22     {
23         if(!flag)
24             try{this.wait();}catch(InterruptedException e){}
25         System.out.println(this.name+"---"+this.amount);
26         
27         this.flag = false;
28         this.notify();
29     }
30 }

结果:

 

おすすめ

転載: www.cnblogs.com/WarBlog/p/12074056.html