• java中的鎖池和等待池

    0
    Java IDE C/C++ 7456 次瀏覽

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

     

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

     

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

     

    等待池:假設一個線程A調用了某個對象的wait()方法,線程A就會釋放該對象的鎖(因為wait()方法必須出現在synchronized中,這樣 自然在執行wait()方法之前線程A就已經擁有了該對象的鎖),同時線程A就進入到了該對象的等待池中。如果另外的一個線程調用了相同對象的 notifyAll()方法,那么處于該對象的等待池中的線程就會全部進入該對象的鎖池中,準備爭奪鎖的擁有權。如果另外的一個線程調用了相同對象的 notify()方法,那么僅僅有一個處于該對象的等待池中的線程(隨機)會進入該對象的鎖池.

     

    下面通過一個例子來說明:

     

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


        package com.tju;  
        class Target  
        {  
            private int count;  
              
            public synchronized void increase()  
            {  
                if(count == 2)  
                {  
                    try  
                    {  
                        wait();  
                    }   
                    catch (InterruptedException e)  
                    {  
                        e.printStackTrace();  
                    }  
                }  
                count++;  
                System.out.println(Thread.currentThread().getName() + ":" + count);  
                notify();  
            }  
              
            public synchronized void decrease()  
            {  
                if(count == 0)  
                {  
                    try  
                    {  
                        //等待,由于Decrease線程調用的該方法,   
                        //所以Decrease線程進入對象t(main函數中實例化的)的等待池,并且釋放對象t的鎖   
                        wait();//Object類的方法   
                    }  
                    catch (InterruptedException e)  
                    {  
                        e.printStackTrace();  
                    }  
                }  
                count--;  
                System.out.println(Thread.currentThread().getName() + ":" + count);  
                  
                //喚醒線程Increase,Increase線程從等待池到鎖池   
                notify();  
            }  
        }  
        class Increase extends Thread  
        {  
            private Target t;  
              
            public Increase(Target t)  
            {  
                this.t = t;  
            }  
            @Override  
            public void run()  
            {     
                for(int i = 0 ;i < 30; i++)  
                {  
                    try  
                    {  
                        Thread.sleep((long)(Math.random()*500));  
                    }  
                    catch (InterruptedException e)  
                    {  
                        e.printStackTrace();  
                    }  
                      
                    t.increase();  
                }  
                  
            }  
              
        }  
        class Decrease extends Thread  
        {  
              
            private Target t;  
            public Decrease(Target t)  
            {  
                this.t = t;  
            }  
              
            @Override  
            public void run()  
            {  
                for(int i = 0 ; i < 30 ; i++)  
                {  
                    try  
                    {  
                        //隨機睡眠0~500毫秒   
                        //sleep方法的調用,不會釋放對象t的鎖   
                        Thread.sleep((long)(Math.random()*500));  
                    }  
                    catch (InterruptedException e)  
                    {  
                        e.printStackTrace();  
                    }  
                      
                    t.decrease();  
                      
                }  
                  
            }  
              
        }  
          
        public class Test  
        {  
            public static void main(String[] args)  
            {  
                Target t = new Target();  
                  
                Thread t1 = new Increase(t);  
                t1.setName("Increase");  
                Thread t2 = new Decrease(t);  
                t2.setName("Decrease");  
                  
                t1.start();  
                t2.start();  
            }  
        }  
    

    相似問題

    相關經驗

    相關資訊

    相關文檔

  • sesese色