Condition ReentrantLock example code
Topic source1. this.wait() 或 condition.await()
a) 共同点
i. 相同流程
1. 解锁并等待
2. 被唤醒后加锁
ii. 应用条件相同
1. 只能在synchronized``或Lock接口的子类上锁的代码段内使用
b) 不同点
i. 不同锁对象
1. wait()的锁对象是它的调用者
2. await()的锁对象是一个Lock子类对象,由他创建了临时开关锁的条件 condition.
ii. 定时自动唤醒
1. await() 可定时自动唤醒
- 1
Junes_99994
import java.util.*;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.TimeUnit;
public class Main {
public static void main(String[] args) throws InterruptedException {
var q = new TaskQueue();
var ts = new ArrayList<Thread>();
for (int i = 0; i < 5; i++) {
final String thNo = "Thread_" + Integer.toString(i + 1);
var t = new Thread(
() -> {
// 执行task:
while (true) {
try {
Thread.sleep(200);
String s = q.getTask(thNo);
System.out.println(thNo + " executing task: " + s);
Thread.sleep(200 + (int) (Math.random() * 400));
System.out.println(thNo + " executed task: " + s);
} catch (InterruptedException e) {
System.out.println("stop task " + thNo);
return;
}
}
});
t.start();
ts.add(t);
}
var add = new Thread(() -> {
for (int i = 0; i < 10; i++) {
// 放入task:
// String s = "t-" + Math.random();
System.out.println("adding task: " + i);
q.addTask(Integer.toString(i));
System.out.println("added task: " + i);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
}
}
});
add.start();
add.join();
System.out.println("waiting for all tasks to complete!");
Thread.sleep(3000);
for (var t : ts) {
t.interrupt();
}
}
}
class TaskQueue {
Queue<String> queue = new LinkedList<>();
private final Lock lock = new ReentrantLock();
private final Condition condition = lock.newCondition();
public void addTask(String s) {
lock.lock();
try {
queue.add(s);
// condition.signalAll();
condition.signal();
} finally {
lock.unlock();
}
}
public String getTask(String tName) throws InterruptedException {
lock.lock();
try {
while (queue.isEmpty()) {
System.out.println(tName + " waiting...");
if (condition.await(1, TimeUnit.SECONDS)) {
// 指定时间内且被其他线程唤醒
System.out.println(tName + " signal awake.");
} else {
// 定时超时唤醒
System.out.println(tName + " self timing awake.");
}
}
System.out.println(tName + " getting task " + queue.element());
return queue.remove();
} finally {// 功能类似回调函数
lock.unlock();
}
}
}