Conditon usage finishing

       Keywords syncronized and wait () and notify () and notifyAll () can be achieved await notification class ReentrantLock can also achieve the same function, but need the help Condition, this class can implement multiple notification, that is to say in a Lock Object Condition where you can create multiple instances (object monitors), thread object can be registered in the specified Condition, so that you can selectively notification thread on the thread more flexible scheduling.

       And syncronized on only a single equivalent of a whole Condition objects Lock objects, all threads are registered in it on top of a thread start notifyAll (when), you need to notify all WAITING thread, there is no choice, there will be a waste of resources. The following is a Demo demo Condition wrong usage.

public class Demo1 {

    private Lock lock = new ReentrantLock ();
    private Condition condition = lock.newCondition ();

    public void await(){
        try {
            condition.await ();
        } catch (InterruptedException e) {
            e.printStackTrace ();
        }
    }

    public static void main(String[] args) {
        Demo1 demo1 = new Demo1 ();
        new Thread (() -> {
            demo1.await ();
        }).start ();

    }

}

After running error: Because before calling Condition.awiat () or single () method needs to call lock.lock () to obtain synchronization monitor, remember, with us using the wait method is to require the use of keywords as a reason synctonized

Exception in thread "Thread-0" java.lang.IllegalMonitorStateException
	at java.util.concurrent.locks.ReentrantLock$Sync.tryRelease(ReentrantLock.java:151)
	at java.util.concurrent.locks.AbstractQueuedSynchronizer.release(AbstractQueuedSynchronizer.java:1261)
	at java.util.concurrent.locks.AbstractQueuedSynchronizer.fullyRelease(AbstractQueuedSynchronizer.java:1723)
	at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2036)
	at Lock.KodyLockTest.ConditionStudy.Demo1.await(Demo1.java:19)
	at Lock.KodyLockTest.ConditionStudy.Demo1.lambda$main$0(Demo1.java:28)
	at java.lang.Thread.run(Thread.java:748)

Double-thread communication Case

public class Demo1 {

    private Lock lock = new ReentrantLock ();
    private Condition condition = lock.newCondition ();

    public void await(){
        try {
            lock.lock ();
            System.out.println (Thread.currentThread ().getName () + "线程获得锁");
            condition.await ();
        } catch (InterruptedException e) {
            e.printStackTrace ();
        }finally {
            System.out.println (Thread.currentThread ().getName () + "线程释放锁");
            lock.unlock ();
        }
    }

    public void single(){
        lock.lock ();
        System.out.println (Thread.currentThread ().getName () + "线程获得锁");
        condition.signal ();
        System.out.println (Thread.currentThread ().getName () + "线程唤醒睡眠线程");
        lock.unlock ();
        System.out.println (Thread.currentThread ().getName () + "线程释放锁");
    }

    public static void main(String[] args) throws InterruptedException{
        Demo1 demo1 = new Demo1 ();
        new Thread (() -> {
            demo1.await ();
        }).start ();
        TimeUnit.SECONDS.sleep (3);

        new Thread (() -> {
            demo1.single ();
        }).start ();

    }

}

Console information: 0 after first thread enters the wait to obtain a lock (lock means giving up the object lock), and after being grabbed thread 1, thread 1 next wake up the waiting thread pool waiting here worth is registered on condition thread, there is only one thread 0, it will wake up, wake up because the thread 0 awakened but you have to continue to run the code required to obtain a lock thread 0 object lock again, this depends on the release did not release the thread 1, released, then thread 0 continues to grab the lock, grab, then run the code after executing eventually released. One thing to remember here is the thread wake up the thread 1 and 0 can not be executed immediately run the code, because you need to remember to grab the lock again, you need to get the lock to be awakened.

Thread-0线程获得锁
Thread-1线程获得锁
Thread-1线程唤醒睡眠线程
Thread-1线程释放锁
Thread-0线程释放锁

Dual-threaded execution alternately

   Using a Condition object identifier plus a run alternately be implemented

package Lock.KodyLockTest.ConditionStudy;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author Heian
 * @time 19/10/13 16:13
 * @description:线程一打印循环打印 我爱你  线程2打印 肖体秀
 */
public class Demo2 {

    private static Lock lock = new ReentrantLock ();
    private static Condition condition = lock.newCondition ();
    //设置一个标识符,如果某个线程打印了则修改标识符位,让自身处于等待,同理另一个线程可以打印
    private static Boolean flag = false;//因为用了线程同步,所以该字面修改是线程可见的

    public static void main(String[] args) {

        new Thread (() -> {
            lock.lock ();
            for (int i=0;i<100;i++){
                try {
                    while (flag == true){
                        condition.await ();
                    }
                    System.out.println ("我爱你");
                    TimeUnit.SECONDS.sleep (1);
                    flag = true;
                    condition.signal ();
                }catch (InterruptedException e){
                    e.printStackTrace ();
                }
            }
            lock.unlock ();
        }).start ();


        new Thread (() -> {
            lock.lock ();
            for (int i=0;i<100;i++){
                try {
                    while (flag == false){
                        condition.await ();
                    }
                    System.out.println ("肖体秀");
                    TimeUnit.SECONDS.sleep (1);
                    flag = false;
                    condition.signal ();
                }catch (InterruptedException e){
                    e.printStackTrace ();
                }
            }
            lock.unlock ();
        }).start ();
    }

}

    Two Condition object implementation, due to the end of the thread lifecycle, it added a! = 10 the judge to immediately release the lock, and not also allow the thread is waiting for

package Lock.KodyLockTest.ConditionStudy;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author Heian
 * @time 19/10/13 16:13
 * @description:线程一打印循环打印 我爱你  线程2打印 肖体秀
 */
public class Demo3 {

    private static Lock lock = new ReentrantLock ();
    private static Condition conditionA = lock.newCondition ();
    private static Condition conditionB = lock.newCondition ();
    private static AtomicInteger atomicIntegerA = new AtomicInteger (0);
    private static AtomicInteger atomicIntegerB = new AtomicInteger (0);

    public static void main(String[] args) {

        new Thread (() -> {
            lock.lock ();
            for (int i=0;i<10;i++){
                try {
                    TimeUnit.SECONDS.sleep (1);
                    System.out.println ("我爱你");
                    conditionB.signal ();//在进入等待池之前先唤醒B,此时A的锁并没有释放
                    if ( atomicIntegerA.incrementAndGet () != 10){
                        conditionA.await ();//如果不是最后一个需要你睡眠,是最后一次的话就直接unlock
                    }
                }catch (InterruptedException e){
                    e.printStackTrace ();
                }
            }
            lock.unlock ();
        }).start ();


        new Thread (() -> {
            lock.lock ();
            for (int i=0;i<10;i++){
                try {
                    TimeUnit.SECONDS.sleep (1);
                    System.out.println ("肖体秀");
                    conditionA.signal ();//在进入等待池之前先唤醒A,此时B的锁并没有释放
                    if ( atomicIntegerB.incrementAndGet () != 10){
                        conditionB.await ();
                    }
                }catch (InterruptedException e){
                    e.printStackTrace ();
                }
            }
            lock.unlock ();
        }).start ();

    }

}

Three or more threads are alternately performed and the order of execution

       Performed alternately case I can refer to: https://blog.csdn.net/qq_40826106/article/details/86607122  Case 7 here I do not judge the end of the thread, plus its own manual on the line, that the execution order is the same.

   When three threads random start, first start assuming that B, B will be in blocking assume then start the C, C will be in the blocking, when run to start A: Here randomly run three threads, to specify that thread execution order by variable num It will awaken B, B executing the wake C, in order to achieve operational ABC order.

package Lock.KodyLockTest.ConditionStudy;

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

/**
 * @author Heian
 * @time 19/10/13 16:13
 * @description: 线程顺序执行
 */
public class Demo4 {

    private static Lock lock = new ReentrantLock ();
    private static Condition conditionA = lock.newCondition ();
    private static Condition conditionB = lock.newCondition ();
    private static Condition conditionC = lock.newCondition ();
    private static int num = 1;

    public static void main(String[] args) {

        Thread threadA = new Thread (() -> {
            try {
                lock.lock ();
                while (num != 1) {
                    conditionA.await ();
                }
                System.out.println ("我爱你肖体秀1");
                num = 2;//事情做完了,就赋值为2
                conditionB.signal ();
            } catch (InterruptedException e) {
                e.printStackTrace ();
            } finally {
                lock.unlock ();
            }
        });

        Thread threadB = new Thread (() -> {
            try {
                lock.lock ();
                while (num != 2) {
                    conditionB.await ();
                }
                System.out.println ("我爱你肖体秀2");
                num = 3;
                conditionC.signal ();
            } catch (InterruptedException e) {
                e.printStackTrace ();
            } finally {
                lock.unlock ();
            }
        });

        Thread threadC = new Thread (() -> {
            try {
                lock.lock ();
                while (num != 3) {
                    conditionC.await ();
                }
                System.out.println ("我爱你肖体秀3");
                num = 3;
                conditionA.signal ();
            } catch (InterruptedException e) {
                e.printStackTrace ();
            } finally {
                lock.unlock ();
            }
        });
        threadB.start ();
        threadA.start ();
        threadC.start ();

    }

}

 

 

 

 

 

 

Published 73 original articles · won praise 18 · views 10000 +

Guess you like

Origin blog.csdn.net/qq_40826106/article/details/102533175