-
2021-03-04 07:10:51
您可以使用比同步语句更灵活的Lock和Condition.
对于您的示例,您可以将obj2替换为ReentrantLock:
@H_403_8@Lock lock2 = new ReentrantLock();
try {
// Blocks until the lock is acquired,just like a `synchronized` statement
lock2.lock();
f1();
synchronized (obj1) {
f2();
lock2.unlock();
obj1.wait();
lock2.lock();
}
}
// Use `finally` to make sure the lock is always released,even if an exception is thrown
finally {
// Exception might have been thrown before current thread could acquire lock again,cannot
// unlock then
if (lock2.isHeldByCurrentThread()) {
lock2.unlock();
}
}
但是,这将允许另一个线程在当前线程开始等待obj1之前获取lock2.如果不希望这样,可以将obj1替换为Lock并等待obj2.
更多相关内容 -
wait会释放锁?当然会释放锁,代码见真招!!!
2021-02-17 23:58:07其实很好理解,从设计的角度很容易分析出wait是会释放锁的。 线程在运行的时候占用了计算机的共享资源,因为当前线程在使用它,然而当前线程进行了休眠例如 wait() 很浅显的道理,当前线程已经停止了,那意味着这个...我在网上看到很多人错误的理解,认为wait不会释放锁,然而它们并没有任何理由,仅凭自己的认知,然后很骄傲的和人讲,wait不会释放锁,你这是误人子弟。殊不知他自己才是误人子弟。
我先讲一讲原理,然后用代码来证明它,让那些还认为wait不会释放锁的同志闭嘴。赶紧改错还来的及
原理
其实很好理解,从设计的角度很容易分析出wait是会释放锁的。
线程在运行的时候占用了计算机的共享资源,因为当前线程在使用它,然而当前线程进行了休眠例如
wait()
很浅显的道理,当前线程已经停止了,那意味着这个资源空闲了下来。那么作为万恶的剥削者"程序员"
肯定不会让这个资源空闲着,你们说对吧!!!因此很容易推断出
wait()
是会释放锁的,而锁的奥义就是控制指定的线程持有共享资源,既然线程都进行了等待,肯定是要需要释放锁的!!!
贴代码前我先讲一下怎么用代码进行证明
很简单,用两个线程同时用一把锁,其中一个线程先执行,并且进行wait()
,如果释放了锁,那么是不是对于另外一个线程来说它就可以抢占到这个锁呢(因为它空闲下来了)而我的代码中为了让两个线程实现这种效果,我让一个线程等待一秒
代码
import java.util.concurrent.TimeUnit; public class Demo { public static void main(String[] args) { Object object=new Object(); final Thread thread1 = new Thread(() -> { System.out.println("线程1开始"); synchronized (object) { try { object.wait();// 进行阻塞,并且释放对象锁 System.out.println("====线程1"); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("线程1结束"); }); final Thread thread2 = new Thread(() -> { System.out.println("线程2开始"); try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (object){ System.out.println("线程2======="); } System.out.println("线程2结束"); }); thread1.start(); thread2.start(); } }
运行结果
从结果中很明显发现wait()
方法会让当前线程释放锁,而线程2等了1s
后,因为线程1释放了锁,因此线程2就能抢占到。
继续证明线程2的
synchronized (object)
在没有获取锁的情况下是会阻塞等待锁释放代码2
import java.util.concurrent.TimeUnit; public class Demo { public static void main(String[] args) { Object object=new Object(); final Thread thread1 = new Thread(() -> { System.out.println("线程1开始"); synchronized (object) { try { TimeUnit.SECONDS.sleep(2000); // 等待足够长时间让我们足以观察到结果 } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("====线程1"); } System.out.println("线程1结束"); }); final Thread thread2 = new Thread(() -> { System.out.println("线程2开始"); try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (object){ System.out.println("线程2=======");// 输出这一句说明当前线程抢占到了锁 } System.out.println("线程2结束"); }); thread1.start(); thread2.start(); } }
-
多线程wait()释放锁吗?那么这个问题怎么解决。
2021-02-28 10:52:14} } } } } 运行结果 Thread-0****9 Thread-0****8 Thread-0****7 Thread-0****6 Thread-0****5 按理来说,线程1抢到锁,然后执行,到wait(),释放锁,应该CPU会运行其他线程,为什么运行到这里就停了(没有完全运行...package thread;
public class TestSleep implements Runnable {
private int time = 10;
private Object lock = new Object();
public static void main(String[] args) {
// TODO Auto-generated method stub
TestSleep a = new TestSleep();
Thread t1 = new Thread(a);
Thread t2 = new Thread(a);
t1.start();
t2.start();
}
@Override
public void run() {
// TODO Auto-generated method stub
synchronized (lock) {
for (int i = 0; i
try {
if (time == 5)
lock.wait();//Thread.sleep(3000);
//lock.notify();
time--;
System.out.println(Thread.currentThread().getName() + "****" + time);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
运行结果
Thread-0****9
Thread-0****8
Thread-0****7
Thread-0****6
Thread-0****5
按理来说,线程1抢到锁,然后执行,到wait(),释放锁,应该CPU会运行其他线程,为什么运行到这里就停了(没有完全运行完,没有真正停止)
-
【18】java锁之wait,notify(wait会释放锁,notify仅仅只是通知,不释放锁)
2017-03-18 00:57:00wait是指在一个已经进入了同步锁的线程内,让自己暂时让出同步锁,以便其他正在等待此锁的线程可以得到同步锁并运行,只有其他线程调用了notify方法(notify并不释放锁,只是告诉调用过wait方法的线程可以去参与获得...wait是指在一个已经进入了同步锁的线程内,让自己暂时让出同步锁,以便其他正在等待此锁的线程可以得到同步锁并运行,只有其他线程调用了notify方法(notify并不释放锁,只是告诉调用过wait方法的线程可以去参与获得锁的竞争了,但不是马上得到锁,因为锁还在别人手里,别人还没释放),调用wait方法的一个或多个线程就会解除wait状态,重新参与竞争对象锁,程序如果可以再次得到锁,就可以继续向下运行。
1)wait()、notify()和notifyAll()方法是本地方法,并且为final方法,无法被重写。
2)当前线程必须拥有此对象的monitor(即锁),才能调用某个对象的wait()方法能让当前线程阻塞。(这种阻塞是通过提前释放synchronized锁,重新去请求锁导致的阻塞,这种请求必须有其他线程通过notify()或者notifyAll()唤醒重新竞争获得锁)
3)调用某个对象的notify()方法能够唤醒一个正在等待这个对象的monitor的线程,如果有多个线程都在等待这个对象的monitor,则只能唤醒其中一个线程; (notify()或者notifyAll()方法并不是真正释放锁,必须等到synchronized方法或者语法块执行完才真正释放锁)
4)调用notifyAll()方法能够唤醒所有正在等待这个对象的monitor的线程,唤醒的线程获得锁的概率是随机的,取决于cpu调度
例子1(错误使用导致线程阻塞):三个线程,线程3先拥有sum对象的锁,然后通过sum.notify()方法通知等待sum锁的线程去获得锁,但是这个时候线程1,2并没有处于wait()导致的阻塞状态,而是在synchronized方法块处阻塞了,所以,这次notify()根本没有通知到线程1,2。然后线程3正常结束,释放掉sum锁,这个时候,线程1就立刻获得了sum对象的锁(通过synchronized获得),然后调用sum.wait()方法释放掉sum的锁,线程2随后获得了sum对象的线程锁(通过synchronized获得),这个时候线程1,2都处于阻塞状态,但是悲催的是,这之后再也没有线程主动调用sum.notify()或者notifyAll()方法显示唤醒这两个线程,所以程序阻塞
Java代码
- public class CyclicBarrierTest {
- public static void main(String[] args) throws Exception {
- final Sum sum=new Sum();
- new Thread(new Runnable() {
- @Override
- public void run() {
- try {
- synchronized (sum) {
- System.out.println("thread3 get lock");
- sum.sum();
- sum.notifyAll(); //此时唤醒没有作用,没有线程等待
- Thread.sleep(2000);
- System.out.println("thread3 really release lock");
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }).start();
- new Thread(new Runnable() {
- @Override
- public void run() {
- try {
- synchronized (sum) {
- System.out.println("thread1 get lock");
- sum.wait();//主动释放掉sum对象锁
- System.out.println(sum.total);
- System.out.println("thread1 release lock");
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }).start();
- new Thread(new Runnable() {
- @Override
- public void run() {
- try {
- synchronized (sum) {
- System.out.println("thread2 get lock");
- sum.wait(); //释放sum的对象锁,等待其他对象唤醒(其他对象释放sum锁)
- System.out.println(sum.total);
- System.out.println("thread2 release lock");
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }).start();
- }
- }
- class Sum{
- public Integer total=0;
- public void sum() throws Exception{
- total=100;
- Thread.sleep(5000);
- }
- }
Java代码
- thread3 get lock
- thread3 really release lock
- thread2 get lock
- thread1 get lock
- //程序后面一直阻塞
例子2:还是上面程序,顺序不同,把线程3放到最下面。最后线程1,2都因为没有再次获得线程导致线程阻塞
运行过程:
线程1先运行获得sum对象锁(通过synchronized),但是随后执行了sum.wait()方法,主动释放掉了sum对象锁,然后线程2获得了sum对象锁(通过synchronized),也通过sum.wait()失去sum的对象锁,最后线程3获得了sum对象锁(通过synchronized),主动通过sum.notify()通知了线程1或者2,假设是1,线程1重新通过notify()/notifyAll()的方式获得了锁,然后执行完毕,随后线程释放锁,然后这个时候线程2成功获得锁,执行完毕。
Java代码
- public class CyclicBarrierTest {
- public static void main(String[] args) throws Exception {
- final Sum sum=new Sum();
- new Thread(new Runnable() {
- @Override
- public void run() {
- try {
- synchronized (sum) {
- System.out.println("thread1 get lock");
- sum.wait();//主动释放sum对象锁,等待唤醒
- System.out.println(sum.total);
- System.out.println("thread1 release lock");
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }).start();
- new Thread(new Runnable() {
- @Override
- public void run() {
- try {
- synchronized (sum) {
- System.out.println("thread2 get lock");
- sum.wait(); //主动释放sum对象锁,等待唤醒
- System.out.println(sum.total);
- System.out.println("thread2 release lock");
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }).start();
- new Thread(new Runnable() {
- @Override
- public void run() {
- try {
- synchronized (sum) {
- System.out.println("thread3 get lock");
- sum.sum();
- sum.notifyAll();//唤醒其他等待线程(线程1,2)
- Thread.sleep(2000);
- System.out.println("thread3 really release lock");
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }).start();
- }
- }
- class Sum{
- public Integer total=0;
- public void sum() throws Exception{
- total=100;
- Thread.sleep(5000);
- }
- }
Java代码
- thread1 get lock
- thread2 get lock
- thread3 get lock
- thread3 really release lock
- 100
- thread2 release lock
- 100
- thread1 release lock
-
wait方法会释放同步块里的所有锁么?
2020-02-28 18:31:06示例代码 public class TestMain { //对象锁一 private static Object lock1 = new Object(); //对象锁二 private static Object lock2 = new Object(); public static void main(String[] args) throws ... -
java多线程中Object.wait()和Condition.await()是否会释放当前线程锁占有的锁
2021-03-09 21:52:53我刚开始深入研究多线程,一直认为Object.wait()/Condition.await()让当前线程阻塞的同时,也会释放当前线程对该condition对象的锁。在之前的一些测试代码中也显示wait后,线程上的锁被释放了。但是我们经理却坚持... -
java线程join方法会释放锁吗
2021-08-25 11:24:36java线程join方法会释放锁吗,虽然join底层使用wait,wait是释放锁的 但当给对象加锁,wait释放的锁是对象的锁,可以认为释放锁 当给线程加锁,wait释放的锁是线程的锁,此时认为不释放锁 wait()和join()的... -
如何证明sleep不释放锁,而wait释放锁?
2021-02-13 00:50:11wait 加锁示例public class WaitDemo {private static Object locker = new Object();public static void main(String[] args) throws InterruptedException {WaitDemo waitDemo = new WaitDemo();// 启动新线程,... -
39.线程间的通信-wait与notify-wait方法自动释放锁与notify方法不会释放锁.mp4
2020-04-06 20:31:30在学习Java过程中,自己收集了很多的Java的学习资料,分享给大家,有需要的欢迎下载,希望对大家有用,一起学习,一起进步。 -
java锁之wait,notify(wait会释放锁,notify仅仅只是通知,不释放锁)
2016-07-29 09:40:59wait是指在一个已经进入了同步锁的线程内,让自己暂时让出同步锁,以便其他正在等待此锁的线程可以得到同步锁并运行, 只有其他线程调用了notify方法(notify并不释放锁,只是告诉调用过wait方法的线程可以去参与... -
java线程类的join方法是否会释放锁,网上很多人说不释放锁,但是join底层使用wait,wait是释放锁的
2018-10-09 15:09:35java线程类的join方法是否会释放锁,网上很多人说不释放锁,但是join底层使用wait,wait是释放锁的 -
wait释放锁的说明
2019-07-16 21:05:28wait释放锁的说明wait仅仅释放调用这个对象的锁 wait仅仅释放调用这个对象的锁 package com.hengyunsoft.msg.future; /** 线程在对象的wait方法上面会释放锁,但是仅仅释放指定对象的锁,比如下面的仅仅释放了锁o2... -
多线程中的wait与sleep到底谁释放了锁
2021-03-09 21:52:52首先,多线程中会使用到两个延迟的函数,wait和sleep。wait是Object类中的方法,...最主要的是sleep方法调用之后,并没有释放锁。使得线程仍然可以同步控制。sleep不会让出系统资源;而wait是进入线程等待池中等待,... -
java多线程什么时候释放锁—wait()、notify()
2019-04-10 12:23:12由于等待一个锁定线程只有在获得这把锁之后,才能恢复运行,所以让持有锁的线程在... 在执行同步代码块的过程中,执行了锁所属对象的wait()方法,这个线程会释放锁,进行对象的等待池。 除了以上情况外,只要持有锁... -
多线程中的wait与sleep到底谁释放了锁?
2021-03-08 23:09:26转载自:https://www.cnblogs.com/yigechengxuyuan/p/8398647.html首先,多线程中会使用到两个延迟的函数,wait和sleep。wait是Object类中的方法,而sleep是Thread类中的方法。sleep是Thread类中的静态方法。无论是... -
Java中sleep()与wait()区别(涉及类锁相关概念)
2021-03-08 23:08:35在区别之前,我们首先先了解一下关于对象锁,类锁的相关概念(当时查阅的详细地址:http://www.importnew.com/20444.html,该作者对类锁和对象锁进行了详细的举例分析)对象锁,类锁在java虚拟机中,每个对象和类在... -
Java同步锁何时释放?
2021-02-28 08:50:52由于等待一个锁定线程只有在获得这把...3. 在执行同步代码块的过程中,执行了锁所属对象的wait()方法,这个线程会释放锁,进行对象的等待池。除了以上情况外,只要持有锁的此案吃还没有执行完同步代码块,就不会释放... -
Java线程之释放锁,释放资源,释放CPU
2021-02-26 19:43:36多线程中的wait与sleep到底谁释放了锁首先,多线程中会使用到两个延迟的函数,wait和sleep。wait是Object类中的方法,而...最主要的是sleep方法调用之后,并没有释放锁。使得线程仍然可以同步控制。sleep不会让出... -
JAVA基础-多线程和锁
2021-01-13 19:14:32线程的基本流程image.png如何中断一个线程方法一:调用interrupt方法,通知线程应该中断了:A.如果线程处于被阻塞状态,那么线程将立即退出被阻塞状态,并抛出了一个InterruptedException异常。...对象锁和类... -
Java并发编程:锁的释放
2021-02-12 15:13:26在讲锁的释放前,我们先讲一下线程的三种主要状态:运行、就绪(可运行)、阻塞。当然,除了这个之外,肯定还有初始状态和结束状态,那个就不讨论了。当我们创建线程之后,还只是进入初始状态,如果我们调用run()方法... -
代码证明使用wait()休眠的线程会释放锁,使用sleep()休眠的线程不会释放锁
2020-06-22 10:59:22设计一个程序证明使用wait()休眠的线程会释放锁,使用sleep()休眠的线程不会释放锁 证明使用wait()休眠的线程会释放锁 package proveWaitAndSleep; import java.io.Serializable; public class Animal implements... -
面试 LockSupport.park()会释放锁资源吗?
2019-10-31 00:04:14他:AQS包含一个状态变量,一个同步队列……balabala……互斥锁balabala,共享锁balabala…… 我:AQS中除了同步队列,还有什么队列? 他:还有个Condition,Condition中有个条件队列…… 我:条件队列和同步队... -
java sleep、wait加锁对象与锁释放
2019-08-07 01:01:38在t1调用sleep之前与之后输出语句,这样,如果运行结果没有t2的运行输出就说明没有释放锁, 如果有输出就说明释放了锁。 这个结果很明显是释放了锁呀,为什么大家都说sleep不释放锁? 其实这混淆了一个概念: ... -
学习:notify()会立刻释放锁么?
2020-12-03 13:20:55学习:notify()会立刻释放锁么? 从咸鱼君0808的文章《notify()会立刻释放锁么?》收货很大,因此写了一点学习小结,并转载了文章。先给出结论,需要等退出synchronized作用范围,才会释放该对象锁,当然如果notify是... -
Java中哪些操作会使线程释放锁资源
2021-04-21 08:59:21线程会释放掉它所占有的“锁标志”,从而使别的线程有机会抢占该锁。 当前线程必须拥有当前对象锁。如果当前线程不是此锁的拥有者,会抛出IllegalMonitorStateException异常。 唤醒当前对象锁的等待线程使用notify或... -
Java多线程之释放对象的锁
2021-03-09 19:18:17由于等待一个锁定线程只有在获得这把...3. 在执行同步代码块的过程中,执行了锁所属对象的wait()方法,这个线程会释放锁,进行对象的等待池。除了以上情况外,只要持有锁的线程还没有执行完同步代码块,就不会释放锁... -
sleep不会释放锁,但是会让出cpu执行权
2020-06-03 15:58:29A线程调用sleep方法不会释放...而wait方法会释放锁(所以前提就是线程在执行wait方法之前必须要获得锁,也就意味着只能在同步方法或者同步代码块中调用wait方法),释放锁之后,必须要有另外线程执行notify或者notifyA.