スレッド拡張編-LOckロックとCondition条件

10375 ワード

説明Synchronized:
synchronizedはJavaのキーワード、すなわちJava言語に内蔵された特性であり、1つのコードブロックがsynchronizedによって修飾された場合、1つのスレッドが対応するロックを取得し、コードブロックを実行すると、他のスレッドは
ロックを取得するスレッドがロックを解除するのを待つしかありません.ロックを取得するスレッドがロックを解除するのは3つの場合があります.
  1).ロックを取得したスレッドはコードブロックを実行し、スレッドはロックの占有を解放する.
  2).スレッド実行に異常が発生した場合、JVMはスレッドに自動的にロックを解除させる.
  3).waitメソッドを呼び出し、待っている間にすぐにロックを解除し、他のスレッドがロックを使用するのを便利にする.
 
ロックの特性:
  1).ロックはJava言語に内蔵されていません.
  2).synchronizedはJVMレベルで実現され、コード実行に異常が発生した場合、JVMは自動的にロックを解放するが、ロックはだめで、ロックが必ず解放されることを保証するには、unLockをfinally{}に置く必要がある(手動で解放する).
  3).資源競争が激しくない場合、Synchronizedの性能はReetarntLockより優れているが、激しい場合、synchronizedの性能は数十倍低下する.
  4).ReentrantLockはロックを追加しました:
    a. void lock();//無条件のロック
    b. void lockInterruptibly throws InterruptedException;//中断可能なロック;
解釈:ReentrantLockを使用してロックを取得したらすぐに戻り、ロックを取得していない場合、現在のスレッドはスリープ状態にあり、ロックを取得するまで、または現在のスレッドが他のスレッドによって中断されて他のことをすることができる.しかしsynchronizedであれば、ロックが取得されなければ、ずっと待っています.
    c. boolean tryLock();//ロックを取得したらすぐにtrueに戻り、他のスレッドが持っている場合はすぐにfalseに戻り、待つことはありません.
    d. boolean tryLock(long timeout,TimeUnit unit);//ロックを取得したらすぐにtrueに戻り、他のスレッドがロックを持っている場合はパラメータが与えた時間を待機し、待機中にロックを取得した場合はtrueに戻り、待機がタイムアウトした場合はfalseに戻る.
 
条件の特性:
    1.Conditionのawait()メソッドはObjectのwait()メソッド、Conditionのsignal()メソッドはObjectのnotify()メソッド、ConditionのsignalAll()はObjectのnotifyAll()メソッドに相当します.異なることに、Objectのこれらの方法は同期ロックとバンドルされて使用される.Conditionは、反発ロック/共有ロックとバンドルして使用する必要があります.
    2.Conditionのより強力な点は、マルチスレッドのスリープと起動をより細かく制御できることです.同じロックの場合、異なる状況で異なるConditionを使用する複数のConditionを作成できます.たとえば、マルチスレッドが同じバッファを読み書きする場合:バッファにデータを書き込むと、「リードスレッド」が呼び出されます.バッファからデータを読み出すと、「書き込みスレッド」が起動します.バッファがいっぱいになると、「書き込みスレッド」は待つ必要があります.バッファが空の場合、リードスレッドは待機する必要があります.     
Objectクラスのwait()、notify()、notifyAll()を使用してバッファを実装する場合、バッファにデータを書き込んだ後に「リードスレッド」を起動する必要がある場合、notify()またはnotifyAll()で「リードスレッド」を明確に指定して起動することはできませんが、notifyAllですべてのスレッドを起動することはできません(ただし、notifyAllでは起動したスレッドがリードスレッドなのか、ライトスレッドなのかは区別できません).しかし,Conditionにより,起動リードスレッドを明確に指定できる.
 
package com.imooc.locks;

import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class Task {
    
    private final Lock lock = new ReentrantLock();
    
    private final Condition addCondition = lock.newCondition();
    
    private final Condition subCondition = lock.newCondition();
    
    
    private static int num = 0;
    private List lists = new LinkedList();
    
    public void add() {
        lock.lock();
        
        try {
            while(lists.size() == 10) {//     , "  "    
                addCondition.await();
            }
            
            num++;
            lists.add("add Banana" + num);
            System.out.println("The Lists Size is " + lists.size());
            System.out.println("The Current Thread is " + Thread.currentThread().getName());
            System.out.println("==============================");
            this.subCondition.signal();
            
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {//   
            lock.unlock();
        }
    }
    
    
    public void sub() {
        lock.lock();
        
        try {
            while(lists.size() == 0) {//      ,"  "    
                subCondition.await();
            }
            
            String str = lists.get(0);
            lists.remove(0);
            System.out.println("The Token Banana is [" + str + "]");
            System.out.println("The Current Thread is " + Thread.currentThread().getName());
            System.out.println("==============================");
            num--;
            addCondition.signal();
            
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }
    
}
package com.imooc.locks;

public class AddThread implements Runnable {
    
    private Task task;
    
    public AddThread(Task task) {
        this.task = task;
    }

    @Override
    public void run() {
        task.add();
    }

}
package com.imooc.locks;

public class SubThread implements Runnable {
    
    private Task task;
    
    public SubThread(Task task) {
        this.task = task;
    }

    @Override
    public void run() {
        task.sub();
    }

}
package com.imooc.locks;

public class TestLock {
    
    public static void main(String[] args) {
        Task task = new Task();
        
        Thread t1=new Thread(new AddThread(task));
        Thread t3=new Thread(new AddThread(task));
        Thread t7=new Thread(new AddThread(task));
        Thread t8=new Thread(new AddThread(task));
        Thread t2 = new Thread(new SubThread(task));
        Thread t4 = new Thread(new SubThread(task));
        Thread t5 = new Thread(new SubThread(task));
        Thread t6 = new Thread(new SubThread(task));
        
        t1.start();
        t2.start();
        t3.start();
        t4.start();
        t5.start();
        t6.start();
        t7.start();
        t8.start();
    }

}

 
転載先:https://www.cnblogs.com/Wanted-Tao/p/6378942.html