java中的鎖池和等待池

在java中,每一個對象都有兩個池,鎖(monitor)池和等待池 java

 

wait() ,notifyAll(),notify() 三個方法都是Object類中的方法. dom

 

鎖池:假設線程A已經擁有了某個對象(注意:不是類)的鎖,而其它的線程想要調用這個對象的某個synchronized方法(或者synchronized塊),因爲這些線程在進入對象的synchronized方法以前必須先得到該對象的鎖的擁有權,可是該對象的鎖目前正被線程A擁有,因此這些線程就進入了該對象的鎖池中。 ide

 

等待池:假設一個線程A調用了某個對象的wait()方法,線程A就會釋放該對象的鎖(由於wait()方法必須出如今synchronized中,這樣天然在執行wait()方法以前線程A就已經擁有了該對象的鎖),同時線程A就進入到了該對象的等待池中。若是另外的一個線程調用了相同對象的notifyAll()方法,那麼處於該對象的等待池中的線程就會所有進入該對象的鎖池中,準備爭奪鎖的擁有權。若是另外的一個線程調用了相同對象的notify()方法,那麼僅僅有一個處於該對象的等待池中的線程(隨機)會進入該對象的鎖池. 函數

 

下面經過一個例子來講明: this

 

要求寫兩個線程,一個線程將某個對象的某個成員變量的值加1,而另一個線程將這個成員變量的值減1.使得該變量的值始終處於[0,2].初始值爲0. spa

 

[java]  view plain copy print ?
  1. package com.tju;  
  2. class Target  
  3. {  
  4.     private int count;  
  5.       
  6.     public synchronized void increase()  
  7.     {  
  8.         if(count == 2)  
  9.         {  
  10.             try  
  11.             {  
  12.                 wait();  
  13.             }   
  14.             catch (InterruptedException e)  
  15.             {  
  16.                 e.printStackTrace();  
  17.             }  
  18.         }  
  19.         count++;  
  20.         System.out.println(Thread.currentThread().getName() + ":" + count);  
  21.         notify();  
  22.     }  
  23.       
  24.     public synchronized void decrease()  
  25.     {  
  26.         if(count == 0)  
  27.         {  
  28.             try  
  29.             {  
  30.                 //等待,因爲Decrease線程調用的該方法,   
  31.                 //因此Decrease線程進入對象t(main函數中實例化的)的等待池,而且釋放對象t的鎖   
  32.                 wait();//Object類的方法   
  33.             }  
  34.             catch (InterruptedException e)  
  35.             {  
  36.                 e.printStackTrace();  
  37.             }  
  38.         }  
  39.         count--;  
  40.         System.out.println(Thread.currentThread().getName() + ":" + count);  
  41.           
  42.         //喚醒線程Increase,Increase線程從等待池到鎖池   
  43.         notify();  
  44.     }  
  45. }  
  46. class Increase extends Thread  
  47. {  
  48.     private Target t;  
  49.       
  50.     public Increase(Target t)  
  51.     {  
  52.         this.t = t;  
  53.     }  
  54.     @Override  
  55.     public void run()  
  56.     {     
  57.         for(int i = 0 ;i < 30; i++)  
  58.         {  
  59.             try  
  60.             {  
  61.                 Thread.sleep((long)(Math.random()*500));  
  62.             }  
  63.             catch (InterruptedException e)  
  64.             {  
  65.                 e.printStackTrace();  
  66.             }  
  67.               
  68.             t.increase();  
  69.         }  
  70.           
  71.     }  
  72.       
  73. }  
  74. class Decrease extends Thread  
  75. {  
  76.       
  77.     private Target t;  
  78.     public Decrease(Target t)  
  79.     {  
  80.         this.t = t;  
  81.     }  
  82.       
  83.     @Override  
  84.     public void run()  
  85.     {  
  86.         for(int i = 0 ; i < 30 ; i++)  
  87.         {  
  88.             try  
  89.             {  
  90.                 //隨機睡眠0~500毫秒   
  91.                 //sleep方法的調用,不會釋放對象t的鎖   
  92.                 Thread.sleep((long)(Math.random()*500));  
  93.             }  
  94.             catch (InterruptedException e)  
  95.             {  
  96.                 e.printStackTrace();  
  97.             }  
  98.               
  99.             t.decrease();  
  100.               
  101.         }  
  102.           
  103.     }  
  104.       
  105. }  
  106.   
  107. public class Test  
  108. {  
  109.     public static void main(String[] args)  
  110.     {  
  111.         Target t = new Target();  
  112.           
  113.         Thread t1 = new Increase(t);  
  114.         t1.setName("Increase");  
  115.         Thread t2 = new Decrease(t);  
  116.         t2.setName("Decrease");  
  117.           
  118.         t1.start();  
  119.         t2.start();  
  120.     }  
  121. }  
相關文章
相關標籤/搜索