更新时间:2022-05-31 09:40:13 来源:极悦 浏览902次
java多线程编程环境下并发是常见问题,这两天看了锁相关的问题,记录下两个简单的用锁实现等待/唤醒机制的demo。
public class WaitAndNotify {
private static boolean flag = true;
private static Object lock = new Object();
public static void main(String[] args) {
Thread waitThread = new Thread(new Wait(), "WaitThread");
waitThread.start();
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
Thread notifyThread = new Thread(new Notify(), "NotifyThread");
notifyThread.start();
}
private static class Wait implements Runnable {
@Override
public void run() {
synchronized (lock) {
while (flag) {
System.out.println(Thread.currentThread() + " flag是true,wait。。" + new SimpleDateFormat("HH:mm:ss").format(new Date()));
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(Thread.currentThread() + " flag是false,开始继续工作" + new SimpleDateFormat("HH:mm:ss").format(new Date()));
}
}
}
private static class Notify implements Runnable {
@Override
public void run() {
synchronized (lock){
System.out.println(Thread.currentThread() + " 持有锁,发出通知" + new SimpleDateFormat("HH:mm:ss").format(new Date()));
lock.notifyAll();
flag = false;
try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
打印结果:
Thread[WaitThread,5,main] flag是true,wait。。18:55:28
Thread[NotifyThread,5,main] 持有锁,发出通知18:55:29
Thread[WaitThread,5,main] flag是false,开始继续工作18:55:34
分析:根据程序可以看到,大致的过程就是:WaitThread拿到lock对象的锁,然后根据flag标记,自己调用了wait()方法,从而释放锁并进入WAITTING状态。NotifyThread此时获取了lock对象的锁,然后进行notify操作,此时WaitThread被唤醒,但是,它不能立刻执行,因为唤醒线程NotifyThread还持有“该对象的同步锁”。必须等到NotifyThread线程释放了“对象的同步锁”之后,也就是同步代码块执行完以后,即睡眠5秒以后,等待线程WaitThread才能获取到“对象的同步锁”进而继续运行。
public class ReenterLockCondition {
private static ReentrantLock lock = new ReentrantLock();
private static Condition condition = lock.newCondition();
private static Runnable runnable = () -> {
try {
lock.lock();
System.out.println(Thread.currentThread().getName() + "进入等待。。");
condition.await();
System.out.println(Thread.currentThread().getName() + "继续执行");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
};
public static void main(String[] args) throws InterruptedException {
Thread thread = new Thread(runnable, "thread--1");
thread.start();
Thread.sleep(2000);
lock.lock();
condition.signal();
System.out.println("主线程发出信号");
lock.unlock();
}
}
打印结果:
thread--1进入等待。。
主线程发出信号
thread--1继续执行
分析:这里thread–1线程是等待线程,主线程就是唤醒想成。开始thread-1启动,拿到锁,然后进入等待并且释放锁,2秒后,主线程拿到锁,然后发出信号并释放锁,最后,thread–1继续执行。
以上就是关于“实现Java锁的两种机制”的介绍,大家如果想了解更多相关知识,不妨来关注一下极悦的Java视频教程,里面的课程内容由浅到深,通俗易懂,即使没有基础也可以听懂,希望对大家的学习能够有所帮助。
0基础 0学费 15天面授
Java就业班有基础 直达就业
业余时间 高薪转行
Java在职加薪班工作1~3年,加薪神器
工作3~5年,晋升架构
提交申请后,顾问老师会电话与您沟通安排学习