精华内容
下载资源
问答
  • java-wait()不会释放所有当前的,怎么办?
    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会释放锁的。 线程在运行的时候占用了计算机的共享资源,因为当前线程在使用它,然而当前线程进行了休眠例如 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();
        }
    
    }
    

    在这里插入图片描述

    展开全文
  • } } } } } 运行结果 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会运行其他线程,为什么运行到这里就停了(没有完全运行完,没有真正停止)

    展开全文
  • wait是指在一个已经进入了同步锁的线程内,让自己暂时让出同步锁,以便其他正在等待此锁的线程可以得到同步锁并运行,只有其他线程调用了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代码  收藏代码

    1. public class CyclicBarrierTest {  
    2.       
    3.     public static void main(String[] args) throws Exception {  
    4.         final Sum sum=new Sum();  
    5.           
    6.         new Thread(new Runnable() {  
    7.             @Override  
    8.             public void  run() {  
    9.                 try {  
    10.                     synchronized (sum) {  
    11.                         System.out.println("thread3 get lock");  
    12.                         sum.sum();  
    13.                         sum.notifyAll(); //此时唤醒没有作用,没有线程等待  
    14.                         Thread.sleep(2000);  
    15.                         System.out.println("thread3 really release lock");  
    16.                     }  
    17.                       
    18.                 } catch (Exception e) {  
    19.                     e.printStackTrace();  
    20.                 }  
    21.             }  
    22.         }).start();  
    23.           
    24.         new Thread(new Runnable() {  
    25.             @Override  
    26.             public void  run() {  
    27.                 try {  
    28.                     synchronized (sum) {  
    29.                         System.out.println("thread1 get lock");  
    30.                         sum.wait();//主动释放掉sum对象锁  
    31.                         System.out.println(sum.total);  
    32.                         System.out.println("thread1 release lock");  
    33.                     }  
    34.                 } catch (Exception e) {  
    35.                     e.printStackTrace();  
    36.                 }  
    37.             }  
    38.         }).start();  
    39.           
    40.         new Thread(new Runnable() {  
    41.             @Override  
    42.             public void  run() {  
    43.                 try {  
    44.                     synchronized (sum) {  
    45.                         System.out.println("thread2 get lock");  
    46.                         sum.wait();  //释放sum的对象锁,等待其他对象唤醒(其他对象释放sum锁)  
    47.                         System.out.println(sum.total);  
    48.                         System.out.println("thread2 release lock");  
    49.                     }  
    50.                 } catch (Exception e) {  
    51.                     e.printStackTrace();  
    52.                 }  
    53.             }  
    54.         }).start();  
    55.     }              
    56. }  
    57.   
    58. class Sum{  
    59.     public Integer total=0;  
    60.       
    61.     public void  sum() throws Exception{  
    62.         total=100;  
    63.         Thread.sleep(5000);  
    64.     }  
    65.       
    66. }  

    Java代码  收藏代码

    1. thread3 get lock  
    2. thread3 really release lock  
    3. thread2 get lock  
    4. thread1 get lock  
    5. //程序后面一直阻塞  

     例子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代码  收藏代码

    1. public class CyclicBarrierTest {  
    2.       
    3.     public static void main(String[] args) throws Exception {  
    4.         final Sum sum=new Sum();  
    5.           
    6.       
    7.           
    8.         new Thread(new Runnable() {  
    9.             @Override  
    10.             public void  run() {  
    11.                 try {  
    12.                     synchronized (sum) {  
    13.                         System.out.println("thread1 get lock");  
    14.                         sum.wait();//主动释放sum对象锁,等待唤醒  
    15.                         System.out.println(sum.total);  
    16.                         System.out.println("thread1 release lock");  
    17.                     }  
    18.                 } catch (Exception e) {  
    19.                     e.printStackTrace();  
    20.                 }  
    21.             }  
    22.         }).start();  
    23.           
    24.         new Thread(new Runnable() {  
    25.             @Override  
    26.             public void  run() {  
    27.                 try {  
    28.                     synchronized (sum) {  
    29.                         System.out.println("thread2 get lock");  
    30.                         sum.wait();  //主动释放sum对象锁,等待唤醒  
    31.                         System.out.println(sum.total);  
    32.                         System.out.println("thread2 release lock");  
    33.                     }  
    34.                 } catch (Exception e) {  
    35.                     e.printStackTrace();  
    36.                 }  
    37.             }  
    38.         }).start();  
    39.           
    40.         new Thread(new Runnable() {  
    41.             @Override  
    42.             public void  run() {  
    43.                 try {  
    44.                     synchronized (sum) {  
    45.                         System.out.println("thread3 get lock");  
    46.                         sum.sum();  
    47.                         sum.notifyAll();//唤醒其他等待线程(线程1,2)  
    48.                         Thread.sleep(2000);  
    49.                         System.out.println("thread3 really release lock");  
    50.                     }  
    51.                       
    52.                 } catch (Exception e) {  
    53.                     e.printStackTrace();  
    54.                 }  
    55.             }  
    56.         }).start();  
    57.           
    58.           
    59.     }  
    60.             
    61. }  
    62.   
    63. class Sum{  
    64.     public Integer total=0;  
    65.       
    66.     public void  sum() throws Exception{  
    67.         total=100;  
    68.         Thread.sleep(5000);  
    69.     }  
    70.       
    71. }  

    Java代码  收藏代码

    1. thread1 get lock  
    2. thread2 get lock  
    3. thread3 get lock  
    4. thread3 really release lock  
    5. 100  
    6. thread2 release lock  
    7. 100  
    8. thread1 release lock  

     

    展开全文
  • 示例代码 public class TestMain { //对象一 private static Object lock1 = new Object(); //对象二 private static Object lock2 = new Object(); public static void main(String[] args) throws ...
  • 我刚开始深入研究多线程,一直认为Object.wait()/Condition.await()让当前线程阻塞的同时,也会释放当前线程对该condition对象的。在之前的一些测试代码中也显示wait后,线程上的释放了。但是我们经理却坚持...
  • java线程join方法会释放锁

    千次阅读 2021-08-25 11:24:36
    java线程join方法会释放锁吗,虽然join底层使用wait,wait是释放锁的 但当给对象加锁,wait释放的锁是对象的锁,可以认为释放锁 当给线程加锁,wait释放的锁是线程的锁,此时认为不释放锁 wait()和join()的...
  • wait 加锁示例public class WaitDemo {private static Object locker = new Object();public static void main(String[] args) throws InterruptedException {WaitDemo waitDemo = new WaitDemo();// 启动新线程,...
  • 在学习Java过程中,自己收集了很多的Java的学习资料,分享给大家,有需要的欢迎下载,希望对大家有用,一起学习,一起进步。
  • wait是指在一个已经进入了同步锁的线程内,让自己暂时让出同步锁,以便其他正在等待此锁的线程可以得到同步锁并运行, 只有其他线程调用了notify方法(notify并不释放锁,只是告诉调用过wait方法的线程可以去参与...
  • java线程类的join方法是否会释放锁,网上很多人说不释放锁,但是join底层使用wait,wait释放锁
  • wait释放锁的说明

    千次阅读 2019-07-16 21:05:28
    wait释放锁的说明wait仅仅释放调用这个对象的锁 wait仅仅释放调用这个对象的锁 package com.hengyunsoft.msg.future; /** 线程在对象的wait方法上面释放锁,但是仅仅释放指定对象的锁,比如下面的仅仅释放了锁o2...
  • 首先,多线程中使用到两个延迟的函数,wait和sleep。wait是Object类中的方法,...最主要的是sleep方法调用之后,并没有释放锁。使得线程仍然可以同步控制。sleep不会让出系统资源;而wait是进入线程等待池中等待,...
  • 由于等待一个锁定线程只有在获得这把锁之后,才能恢复运行,所以让持有锁的线程在... 在执行同步代码块的过程中,执行了锁所属对象的wait()方法,这个线程会释放锁,进行对象的等待池。 除了以上情况外,只要持有锁...
  • 转载自:https://www.cnblogs.com/yigechengxuyuan/p/8398647.html首先,多线程中使用到两个延迟的函数,wait和sleep。wait是Object类中的方法,而sleep是Thread类中的方法。sleep是Thread类中的静态方法。无论是...
  • 在区别之前,我们首先先了解一下关于对象,类的相关概念(当时查阅的详细地址:http://www.importnew.com/20444.html,该作者对类和对象进行了详细的举例分析)对象,类java虚拟机中,每个对象和类在...
  • Java同步何时释放

    2021-02-28 08:50:52
    由于等待一个锁定线程只有在获得这把...3. 在执行同步代码块的过程中,执行了锁所属对象的wait()方法,这个线程会释放锁,进行对象的等待池。除了以上情况外,只要持有锁的此案吃还没有执行完同步代码块,就不会释放...
  • 多线程中的wait与sleep到底谁释放了锁首先,多线程中使用到两个延迟的函数,wait和sleep。wait是Object类中的方法,而...最主要的是sleep方法调用之后,并没有释放锁。使得线程仍然可以同步控制。sleep不会让出...
  • JAVA基础-多线程和

    千次阅读 2021-01-13 19:14:32
    线程的基本流程image.png如何中断一个线程方法一:调用interrupt方法,通知线程应该中断了:A.如果线程处于被阻塞状态,那么线程将立即退出被阻塞状态,并抛出了一个InterruptedException异常。...对象和类...
  • 在讲释放前,我们先讲一下线程的三种主要状态:运行、就绪(可运行)、阻塞。当然,除了这个之外,肯定还有初始状态和结束状态,那个就不讨论了。当我们创建线程之后,还只是进入初始状态,如果我们调用run()方法...
  • 设计一个程序证明使用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()立刻释放锁么? 从咸鱼君0808的文章《notify()立刻释放锁么?》收货很大,因此写了一点学习小结,并转载了文章。先给出结论,需要等退出synchronized作用范围,才释放该对象锁,当然如果notify是...
  • Java中哪些操作使线程释放锁资源

    千次阅读 2021-04-21 08:59:21
    线程会释放掉它所占有的“标志”,从而使别的线程有机会抢占该。 当前线程必须拥有当前对象。如果当前线程不是此的拥有者,抛出IllegalMonitorStateException异常。 唤醒当前对象的等待线程使用notify或...
  • 由于等待一个锁定线程只有在获得这把...3. 在执行同步代码块的过程中,执行了锁所属对象的wait()方法,这个线程会释放锁,进行对象的等待池。除了以上情况外,只要持有锁的线程还没有执行完同步代码块,就不会释放锁...
  • A线程调用sleep方法不会释放...而wait方法会释放锁(所以前提就是线程在执行wait方法之前必须要获得锁,也就意味着只能在同步方法或者同步代码块中调用wait方法),释放锁之后,必须要有另外线程执行notify或者notifyA.

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 103,911
精华内容 41,564
关键字:

java wait会释放锁吗

java 订阅