Java 多線程, 同步訪問, 線程鎖,鎖對象,ReentrantLock,synchronized


1.為什么要同步訪問數據?

  當兩個或以上的線程需要共享對同一數據的存取,可能會發生共享數據的訛誤。

2.實現同步的方式

  2.1 ReentrantLock類

    School類:

        class School{
        
            private int stuNum;
            private Lock lock;        private Condition condition;
        
            public School(int stuNum) {
                this.stuNum = stuNum;
                lock = new ReentrantLock(); condition = lock.newCondition();
            }
        ......

    其中 lock是鎖對象, condition 是條件對象,

    用法:

        public void stuNums1(){
            lock.lock();
            try{
                while (stuNum < 20){
                    System.out.println(stuNum+" < 20,等待數量變為20");
                    condition.await();
                }
                stuNum -= 5;
                System.out.println(Thread.currentThread().toString() + ":" + stuNum);
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }

        }
        public void stuNums2(){
            lock.lock();
            try{
                stuNum += 1;
                System.out.println(Thread.currentThread().toString() + ":" + stuNum);
                if (stuNum >= 20){
                    System.out.println(stuNum + ">20了,開始喚醒等待集的線程");
                    condition.signalAll();
                }
            } finally {
                lock.unlock();
            }

        }

    當條件對象調用await()方法時候,當前線程會進入等待集,處於阻塞狀態,直到其他線程在同一條件上調用signalAll()方法為止。

    當一個線程調用await()方法時候,沒有辦法重新激活自身,寄希望於其他線程,如果沒有其他線程重新激活等待中的線程,將會導致死鎖。

    在對象狀態有利於等待線程的方向改變時調用signalAll()方法,解除等待線程的阻塞。

  2.2 synchronized關鍵字

    在聲明方法時,加上這個關鍵字,對象鎖會保護整個方法。其效果等價於2.1中的方法。

    在這里  wait() notufyAll() 分別等價於 await() signalAll()方法。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM