Lock基本使用
- Lock lock = new ReentrantLock(); 创建一个lock对象,在lock.lock() 与 lock.unLock() 之间的部分互斥执行,类似于synchronize。例一
- Condition conditionA = lock.newCondition(); 创建一个Condition对象,可以使用await() 方法和signal()方法,可使用一个condition对象创建多个Condition对象,达到线程组的等待和唤醒操作。在调用lock.await()或者lock.signal()前要进行lock.lock()。例二
- 经典问题消费者生产者问题,多个线程使用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();
}
}
}