Lock基本使用,Condition线程分组等待唤醒,生产者消费者问题

Lock基本使用

  1. Lock lock = new ReentrantLock(); 创建一个lock对象,在lock.lock() 与 lock.unLock() 之间的部分互斥执行,类似于synchronize。例一
  2. Condition conditionA = lock.newCondition(); 创建一个Condition对象,可以使用await() 方法和signal()方法,可使用一个condition对象创建多个Condition对象,达到线程组的等待和唤醒操作。在调用lock.await()或者lock.signal()前要进行lock.lock()。例二
  3. 经典问题消费者生产者问题,多个线程使用signal可能导致假死,与synchronize相同,可以使用signalAll方式解决。可以用conditionP和conditionC进行等待/唤醒。例三

例一:


import javax.sound.midi.Soundbank;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

// lock使用: 在lock() 与 unlock() 之间代码执行互斥 与 synchronize类似
// 使用Condition condition = lock.newCondition() 实现等待/通知
// 使用 condition.await() 或者 condition.signal() 之前要先使用lock()加锁 也可以使用signalAll() 释放掉所有await()
class Service01 {
    
    
    private Lock lock = new ReentrantLock();
    private Condition condition = lock.newCondition();

    public void await() {
    
    
        try {
    
    
            lock.lock();
            System.out.println("await时间为:" + System.currentTimeMillis());
            condition.await();
        } catch (InterruptedException e) {
    
    
            e.printStackTrace();
        } finally {
    
    
            lock.unlock();
        }
    }

    public void signal() {
    
    
        try {
    
    
            lock.lock();
            System.out.println("signal的时间为:" + System.currentTimeMillis());
            condition.signal();
        } finally {
    
    
            lock.unlock();
        }
    }

    public void signalAll() {
    
    
        try {
    
    
            lock.lock();
            System.out.println("signalAA 执行时间:" + System.currentTimeMillis());
            condition.signalAll();
        } finally {
    
    
            lock.unlock();
        }
    }
}

class ThreadA extends Thread {
    
    
    private Service01 service01;

    public ThreadA(Service01 service01) {
    
    
        this.service01 = service01;
    }

    @Override
    public void run() {
    
    
        service01.await();
    }
}

public class StudyThreads01Lock基本用法 {
    
    
    public static void main(String[] args) throws InterruptedException {
    
    
        Service01 service01 = new Service01();
        ThreadA threadA = new ThreadA(service01);

        threadA.start();
        Thread.sleep(2000);
        service01.signal();

        System.out.println("========================");

        Service01 service02 = new Service01();
        ThreadA threadA1 = new ThreadA(service02);
        ThreadA threadA2 = new ThreadA(service02);
        ThreadA threadA3 = new ThreadA(service02);
        ThreadA threadA4 = new ThreadA(service02);
        ThreadA threadA5 = new ThreadA(service02);
        threadA1.start();
        threadA2.start();
        threadA3.start();
        threadA4.start();
        threadA5.start();

        Thread.sleep(5000);
        service02.signalAll();
    }
}

例二:

package com.chapter04;

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

class Service02 {
    
    
    private Lock lock = new ReentrantLock();
    private Condition conditionA = lock.newCondition();
    private Condition conditionB = lock.newCondition();

    public void awaitA() {
    
    
        try {
    
    
            lock.lock();
            System.out.println("awaitA 开始时间:" + new Date());
            conditionA.await();
            System.out.println("awaitA 结束时间:" + new Date());
        } catch (InterruptedException e) {
    
    
            e.printStackTrace();
        } finally {
    
    
            lock.unlock();
        }
    }

    public void awaitB() {
    
    
        try {
    
    
            lock.lock();
            System.out.println("awaitB 开始时间:" + new Date());
            conditionB.await();
            System.out.println("awaitB 结束时间:" + new Date());
        } catch (InterruptedException e) {
    
    
            e.printStackTrace();
        } finally {
    
    
            lock.unlock();
        }
    }

    public void signalAllA() {
    
    
        try {
    
    
            lock.lock();
            System.out.println("signalAllA 时间:" + new Date());
            conditionA.signalAll();
        } finally {
    
    
            lock.unlock();
        }
    }

    public void signalAllB() {
    
    
        try {
    
    
            lock.lock();
            System.out.println("signalB时间:" + new Date());
            conditionB.signalAll();
        } finally {
    
    
            lock.unlock();
        }
    }
}

class ThreadA02 extends Thread {
    
    
    private Service02 service02;

    public ThreadA02(Service02 service02) {
    
    
        this.service02 = service02;
    }

    @Override
    public void run() {
    
    
        service02.awaitA();
    }
}

class ThreadB02 extends Thread {
    
    
    private Service02 service02;

    public ThreadB02(Service02 service02) {
    
    
        this.service02 = service02;
    }

    @Override
    public void run() {
    
    
        service02.awaitB();
    }
}

public class StudyThreads02使用Condition实现线程分组唤醒 {
    
    
    public static void main(String[] args) throws InterruptedException {
    
    
        Service02 service02 = new Service02();
        ThreadA02 threadA02_1 = new ThreadA02(service02);
        ThreadA02 threadA02_2 = new ThreadA02(service02);
        ThreadA02 threadA02_3 = new ThreadA02(service02);
        ThreadA02 threadA02_4 = new ThreadA02(service02);

        ThreadB02 threadB02_1 = new ThreadB02(service02);
        ThreadB02 threadB02_2 = new ThreadB02(service02);
        ThreadB02 threadB02_3 = new ThreadB02(service02);
        ThreadB02 threadB02_4 = new ThreadB02(service02);

        threadA02_1.start();
        threadA02_2.start();
        threadA02_3.start();
        threadA02_4.start();

        threadB02_1.start();
        threadB02_2.start();
        threadB02_3.start();
        threadB02_4.start();

        Thread.sleep(5000);

        service02.signalAllA();
    }
}

例三:

package com.chapter04;

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

class MyService03 {
    
    
    private Lock lock = new ReentrantLock();
    private Condition conditionP = lock.newCondition();
    private Condition conditionC = lock.newCondition();
    private Condition condition = lock.newCondition();
    volatile private boolean hasValue = true;

    public void P() {
    
    
        try {
    
    
            lock.lock();
            while (hasValue) {
    
    
                System.out.println("进入生产者,此时有产品需要等待:" + hasValue);
                // 有产品 生产者等待
                conditionP.await();
            }
            System.out.println(Thread.currentThread().getName() + "=== 生产者-- 生产 --了一个产品");
            hasValue = true;
            System.out.println("结束生产者,此时:" + hasValue);
            // 生产了一个产品,唤醒消费者
            conditionC.signalAll();
        } catch (InterruptedException e) {
    
    
            e.printStackTrace();
        } finally {
    
    
            lock.unlock();
        }
    }

    public void C() {
    
    
        try {
    
    
            lock.lock();
            while (!hasValue) {
    
    
                System.out.println("进入消费者,此时无产品需要等待:" + hasValue);
                // 此时无产品,消费者需要等待
                conditionC.await();
            }
            System.out.println(Thread.currentThread().getName() + "=== 消费者-- 消费 --了一个产品");
            hasValue = false;
            System.out.println("结束消费者,此时:" + hasValue);
            // 消费了一个产品,唤醒生产者进行生产
            conditionP.signalAll();
        } catch (InterruptedException e) {
    
    
            e.printStackTrace();
        } finally {
    
    
            lock.unlock();
        }
    }
}

class ThreadP03 extends Thread {
    
    
    private MyService03 myService03;

    public ThreadP03(MyService03 myService03) {
    
    
        this.myService03 = myService03;
    }

    @Override
    public void run() {
    
    
        for (int i = 0; i < 10; i++) {
    
    
            myService03.P();
        }
    }
}

class ThreadC03 extends Thread {
    
    
    private MyService03 myService03;

    public ThreadC03(MyService03 myService03) {
    
    
        this.myService03 = myService03;
    }

    @Override
    public void run() {
    
    
        for (int i = 0; i < 10; i++) {
    
    
            myService03.C();
        }
    }
}

public class StudyThreads03生产者消费者在Lock中的使用 {
    
    
    public static void main(String[] args) {
    
    
        MyService03 service03 = new MyService03();

        ThreadP03[] threadP03s = new ThreadP03[10];
        ThreadC03[] threadC03s = new ThreadC03[10];
        for (int i = 0; i < 10; i++) {
    
    
            threadC03s[i] = new ThreadC03(service03);
            threadP03s[i] = new ThreadP03(service03);
            threadC03s[i].start();
            threadP03s[i].start();
        }
    }
}

猜你喜欢

转载自blog.csdn.net/weixin_43960044/article/details/121121983