精华内容
下载资源
问答
  • java wait方法浅析

    2021-02-28 10:52:11
    下面的文章就是对java wait方法的一个简单介绍,具体的通过代码来了解哦,一起来看看吧。wait方法是让当前线程等待,注意,这里的当前线程指的不是t,指的是主线程,wait会释放锁,等到其他线程调用notify方法的时候...

    对于java wait你都了解多少呢?下面的文章就是对java wait方法的一个简单介绍,具体的通过代码来了解哦,一起来看看吧。

    wait方法是让当前线程等待,注意,这里的当前线程指的不是t,指的是主线程,wait会释放锁,等到其他线程调用notify方法的时候再继续运行。

    下面可以一起通过下面的例子来了解一下。

    例子:package com.citi.test.mutiplethread.demo0503;

    import java.util.Date;

    public class WaitTest

    {

    public static void main(String[] args)

    {

    ThreadA t1 = new ThreadA("t1");

    System.out.println("t1:" + t1);

    synchronized(t1)

    {

    try

    {

    //启动线程

    System.out.println(Thread.currentThread()

    .getName() + " start t1");

    t1.start();

    //主线程等待t1通过notify唤醒。

    System.out.println(Thread.currentThread()

    .getName() + " wait()" + new Date());

    t1.wait(); // 不是使t1线程等待,而是当前执行wait的线程等待

    System.out.println(Thread.currentThread()

    .getName() + " continue" + new Date());

    }

    catch (Exception e)

    {

    e.printStackTrace();

    }

    }

    }

    }

    class ThreadA extends Thread

    {

    public ThreadA(String name)

    {

    super(name);

    }

    @Override

    public void run()

    {

    synchronized(this)

    {

    System.out.println("this:" + this);

    try

    {

    Thread.sleep(2000); //使当前线程阻塞1秒

    }

    catch (InterruptedException e)

    {

    // TODO Auto-generated catch block

    e.printStackTrace();

    }

    System.out.println(Thread.currentThread()

    .getName() + " call notify()");

    this.notify();

    }

    }

    }

    执行结果:

    0914f7abc0c206c882fcd40319f78587.png

    synchronized(this),和synchronized(t1),锁的是同一个对象。

    这个程序一共有两个线程,一个是主线程main,另外一个是线程t1,所以会有锁的竞争,因为是main方法先运行到第9行,所以先获取到锁。

    这样的话,就导致了32行到40行的代码必须在main主线程释放锁时才运行。

    t1.await()释放了锁,所以看执行结果,32行在15行之后执行,17行会等待t1线程执行完毕调用notify之后再执行。

    这里的话就说明了,代码中t1.await(),是让运行这行代码的线程等待,不是让t1这个线程等待。

    以上就是全部的内容了,希望可以对你有所帮助,更多java常见问题及解决方法,请继续关注奇Q工具网来进行一下了解吧!

    推荐阅读:

    展开全文
  • wait(): Causes the current thread to wait until another thread invokes the notify() method or the notifyAll() method for this object.notify(): Wakes up a single thread that is waiting on this object's...

    wait(): Causes the current thread to wait until another thread invokes the notify() method or the notifyAll() method for this object.

    notify(): Wakes up a single thread that is waiting on this object's monitor.

    notifyAll(): Wakes up all threads that are waiting on this object's monitor.

    这三个方法都是Java语言提供的实现线程间阻塞(Blocking)和控制进程内调度(inter-process communication)的底层机制。在解释如何使用前,先说明一下两点:

    1. 正如Java内任何对象都能成为锁(Lock)一样,任何对象也都能成为条件队列(Condition queue)。而这个对象里的wait(), notify()和notifyAll()则是这个条件队列的固有(intrinsic)的方法。

    2. 一个对象的固有锁和它的固有条件队列是相关的,为了调用对象X内条件队列的方法,你必须获得对象X的锁。这是因为等待状态条件的机制和保证状态连续性的机制是紧密的结合在一起的。

    (An object's intrinsic lock and its intrinsic condition queue are related: in order to call any of the condition queue methods on object X, you must hold the lock on X. This is because the mechanism for waiting for state-based conditions is necessarily tightly bound to the mechanism fo preserving state consistency)

    根据上述两点,在调用wait(), notify()或notifyAll()的时候,必须先获得锁,且状态变量须由该锁保护,而固有锁对象与固有条件队列对象又是同一个对象。也就是说,要在某个对象上执行wait,notify,先必须锁定该对象,而对应的状态变量也是由该对象锁保护的。

    3.永远在循环(loop)里调用 wait 和 notify,不是在 If 语句

    知道怎么使用后,来探讨一下使用中的一些问题:

    1. 执行wait, notify时,不获得锁会如何?请看代码:

    public static void main(String[] args) throws InterruptedException {

    Object obj = new Object();

    obj.wait();

    obj.notifyAll();

    }

    执行以上代码,会抛出java.lang.IllegalMonitorStateException的异常。

    2. 执行wait, notify时,不获得该对象的锁会如何?请看代码:

    public static void main(String[] args) throws InterruptedException {

    Object obj = new Object();

    Object lock = new Object();

    synchronized (lock) {

    obj.wait();

    obj.notifyAll();

    }

    }

    执行代码,同样会抛出java.lang.IllegalMonitorStateException的异常。

    3. 为什么在执行wait, notify时,必须获得该对象的锁?

    这是因为,如果没有锁,wait和notify有可能会产生竞态条件(Race Condition)。考虑以下生产者和消费者的情景:

    1.1生产者检查条件(如缓存满了)-> 1.2生产者必须等待

    2.1消费者消费了一个单位的缓存 -> 2.2重新设置了条件(如缓存没满) -> 2.3调用notifyAll()唤醒生产者

    我们希望的顺序是: 1.1->1.2->2.1->2.2->2.3

    但在多线程情况下,顺序有可能是 1.1->2.1->2.2->2.3->1.2。也就是说,在生产者还没wait之前,消费者就已经notifyAll了,这样的话,生产者会一直等下去。

    所以,要解决这个问题,必须在wait和notifyAll的时候,获得该对象的锁,以保证同步。

    请看以下利用wait,notify实现的一个生产者、一个消费者和一个单位的缓存的简单模型

    public class QueueBuffer {

    int n;

    boolean valueSet = false;

    synchronized int get() {

    if (!valueSet)

    try {

    wait();

    } catch (InterruptedException e) {

    System.out.println("InterruptedException caught");

    }

    System.out.println("Got: " + n);

    valueSet = false;

    notify();

    return n;

    }

    synchronized void put(int n) {

    if (valueSet)

    try {

    wait();

    } catch (InterruptedException e) {

    System.out.println("InterruptedException caught");

    }

    this.n = n;

    valueSet = true;

    System.out.println("Put: " + n);

    notify();

    }

    }

    public class Producer implements Runnable {

    private QueueBuffer q;

    Producer(QueueBuffer q) {

    this.q = q;

    new Thread(this, "Producer").start();

    }

    public void run() {

    int i = 0;

    while (true) {

    q.put(i++);

    }

    }

    }

    public class Consumer implements Runnable {

    private QueueBuffer q;

    Consumer(QueueBuffer q) {

    this.q = q;

    new Thread(this, "Consumer").start();

    }

    public void run() {

    while (true) {

    q.get();

    }

    }

    }

    public class Main {

    public static void main(String[] args) {

    QueueBuffer q = new QueueBuffer();

    new Producer(q);

    new Consumer(q);

    System.out.println("Press Control-C to stop.");

    }

    }

    所以,JVM通过在执行的时候抛出IllegalMonitorStateException的异常,来确保wait, notify时,获得了对象的锁,从而消除隐藏的Race Condition。

    最后来看看一道题:写一个多线程程序,交替输出1,2,1,2,1,2...... 利用wait, notify解决:

    public class OutputThread implements Runnable {

    private int num;

    private Object lock;

    public OutputThread(int num, Object lock) {

    super();

    this.num = num;

    this.lock = lock;

    }

    public void run() {

    try {

    while(true){

    synchronized(lock){

    lock.notifyAll();

    lock.wait();

    System.out.println(num);

    }

    }

    } catch (InterruptedException e) {

    // TODO Auto-generated catch block

    e.printStackTrace();

    }

    }

    public static void main(String[] args){

    final Object lock = new Object();

    Thread thread1 = new Thread(new OutputThread(1,lock));

    Thread thread2 = new Thread(new OutputThread(2, lock));

    thread1.start();

    thread2.start();

    }

    }

    《Java Concurrency in Practice》里的第14章,对wait, notify有更加详细的介绍。

    参考:

    展开全文
  • 每当对象上调用wait()方法时,它都会导致当前线程等待,直到另一个线程为此对象调用notify()或notifyAll()方法,而wait(long timeout)导致当前线程等待直到另一个线程线程为此对象调用notify()或notifyAll()方法,...

    每当在对象上调用wait()方法时,它都会导致当前线程等待,直到另一个线程为此对象调用notify()或notifyAll()方法,而wait(long timeout)导致当前线程等待直到另一个线程线程为此对象调用notify()或notifyAll()方法,或者指定的超时时间已经过去。

    等待()

    在下面的程序中,当在对象上调用wait()时,线程从运行状态进入等待状态。它等待其他线程调用notify()或notifyAll()使其进入可运行状态,从而形成死锁。

    示例class MyRunnable implements Runnable {

    public void run() {

    synchronized(this) {

    System.out.println("In run() method");

    try {

    this.wait();

    System.out.println("Thread in waiting state, waiting for some other threads on same object to call notify() or notifyAll()");

    } catch (InterruptedException ie) {

    ie.printStackTrace();

    }

    }

    }

    }

    public class WaitMethodWithoutParameterTest {

    public static void main(String[] args) {

    MyRunnable myRunnable = new MyRunnable();

    Thread thread = new Thread(myRunnable, "Thread-1");

    thread.start();

    }

    }

    输出结果In run() method

    等待(长)

    在下面的程序中,在对象上调用wait(1000)时,即使在超时时间过后未调用notify()或notifyAll(),线程也会从运行状态进入等待状态,线程将从等待状态变为可运行状态。

    示例class MyRunnable implements Runnable {

    public void run() {

    synchronized(this) {

    System.out.println("In run() method");

    try {            this.wait(1000);

    System.out.println("Thread in waiting state, waiting for some other threads on same object to call notify() or notifyAll()");

    } catch (InterruptedException ie) {

    ie.printStackTrace();

    }

    }

    }

    }

    public class WaitMethodWithParameterTest {

    public static void main(String[] args) {

    MyRunnable myRunnable = new MyRunnable();

    Thread thread = new Thread(myRunnable, "Thread-1");

    thread.start();

    }

    }

    输出结果In run() method

    Thread in waiting state, waiting for some other threads on same object to call notify() or notifyAll()

    展开全文
  • java线程wait方法

    2021-02-12 10:28:48
    wait和notify是用多线程竞争同一锁资源的情况下使用的。你这32313133353236313431303231363533e78988e69d8331333335303436段代码实际是个单线程,这个线程自己把自己阻塞了,自然不可能自己把自己唤醒。你的意图...

    wait和notify是用在多线程竞争同一锁资源的情况下使用的。

    你这32313133353236313431303231363533e78988e69d8331333335303436段代码实际是个单线程,这个线程自己把自己阻塞了,自然不可能自己把自己唤醒。

    你的意图怎么实现呢?需要加入另外一个线程,下面是我仿照你的意图写的一段代码,供参考下

    public class A

    {

    public A(){

    final A a = this;

    Thread th1 = new Thread(){

    @Override

    public void run(){

    //一直循环,去尝试着唤醒a

    try

    {

    this.sleep(10000);

    } catch (InterruptedException e)

    {

    // TODO Auto-generated catch block

    e.printStackTrace();

    }//为检查是不是能真正实现唤醒a,等待10000毫秒,此时保证a已经处于等待状态中。

    while(true){

    /**

    * 用notify唤醒的线程必须是持有当前锁对象的线程

    */

    synchronized (a){

    a.notify();

    }

    }

    }

    };

    th1.setDaemon(true);//这句也是必须的,将th1设为守护线程,保证在唤醒a以后,所有活动的线程都为守护线程,jvm能及时推出

    th1.start();//和a.run的顺序不可以换

    this.run();

    }

    public static void main(String[] args)

    {

    new A();

    }

    public void run()

    {

    /**

    * 这里可以换成这样,直接锁住this就行了

    */

    synchronized (this)

    {

    try

    {

    this.wait();//阻塞当前的线程

    } catch (InterruptedException e)

    {

    // TODO Auto-generated catch block

    e.printStackTrace();

    }finally{

    System.out.println("1");//执行finally

    }

    }

    }

    }

    展开全文
  • wait()方法的作用是让当前线程进行等待也就是让线程停止执行,并且wait()方法方是Object里的方法所有的对象默认都有此方法。notify()方法的作用是让已经被wait()方法停止的线程继续执行,notify()方法wait()方法...
  • 如果wait()方法同步块中,代码的确会抛出异常.并且有 Lost Wake-Up Problem
  • 解决方法:这时静态常量对象的wait方法和notify方法就可以上场了。 详细: 1.void notify() 唤醒此对象监视器上等待的单个线程。 void notifyAll() 唤醒此对象监视器上等待的所有线程。 void wai...
  • 1.wait方法和notify方法这两个方法,包括...Java API中,wait方法的定义如下:public finalvoidwait()throws InterruptedExceptionCauses the current thread to wait until another thread invokes thenotify(...
  • java wait()方法用法详解

    千次阅读 2021-02-12 12:27:15
    一、wait(), notify(), notifyAll()等方法介绍1.wait()的作用是让当前线程进入等待状态,同时,wait()也会让当前线程释放它所持有的锁。“直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法”,当前线程被...
  • 它们是有 synchronized标记的方法或 synchronized块中调用的,因为 wait 和 nodify 需要监视对其调用的 Object。大多数Java开发人员都知道对象类的 wait(),notify() 和 notifyAll() 方法必须 Java 中的 ...
  • oracle中UPDATE nowait使用方法介绍1、UPDATE nowait 应用以下场景:查询某条数据,并对其开启数据库事务。如果查询的当前数据没有加锁,则正确返回结果,并对当前数据加锁,如果查询的当前数据已事务中,已...
  • Object类的JavaDoc中,在方法wait(long timeout)中,如下所述“If the current thread is interrupted by any thread before or while it is waiting, then an InterruptedException is thrown”上述陈述中“之前”...
  • void ObjectMonitor::wait(jlong millis, boolinterruptible, TRAPS) {Thread* const Self =THREAD ;assert(Self->is_Java_thread(), "Must be Java thread!");JavaThread*jt = (JavaThread *)THREAD;DeferredIni...
  • 发现满了,在wait里面等了 P3 想来放,发现满了,在wait里面等了 C1想来拿, C2, C3 就get里面等着 C1开始执行, 获取1, 然后调用notify 然后退出 如果C1把C2唤醒了, 所以P2 (其他的都得等.)只能put方法上等着....
  • Java中sleep和wait这两个方法都可以用来进行线程控制,但是它们在使用上有什么区别呢?本质区别首先,要记住这个差别,“sleep是Thread类的方法wait是Object类中定义的方法”。尽管这两个方法都会影响线程的执行...
  • Java线程通讯方法wait()、nofity() 详解本文将探讨以下问题:synchronized 代码块使用notify()与notifyAll()的区别Java wait(),notify()如何使用synchronized 代码块使用我们知道当多个线程同时访问一个线程安全...
  • Java语言中内建了对于多线程的支持,可以非常方便的创建、控制线程以及线程之间进行同步操作。...特别地,为了提供对于程序健壮性方面的考虑,Java中提供了对于wait方法超时语意的支持。但是Java对于wa...
  • 为什么 wait方法必须 synchronized保护的同步代码中使用? 为什么 wait/notify/notifyAll 被定义 Object 类中,而 sleep 定义 Thread 类中? wait/notify 和 sleep 方法的异同? 为什么 wait 必须 ...
  • public class ObjectWait { static class A implements Runnable{ Object object; A(Object object){ this.object=object; } @Override public void run() { synchronized (object){ tr
  • Thread wait使用

    2021-06-15 21:25:33
    闲来无事,看了下thread ,sleep方法写着不会释放任何锁,然后想起来Object的wait方法会释放锁,然后进行等待,直到notify调用。object必须锁里,使用sychronized。 那么就有一个问题,如果使用Lock呢? 看代码是...
  • 锁定受保护的数据结构上。线程是访问数据结构的东西。这些锁位于数据结构对象上,以防止线程以不安全的方式访问数据结构。任何对象都可以用作内部锁(意为与同步结合使用)。这样,您可以通过将synchronized修饰符...
  • 所有对象的非同步方法都能任意时刻被任意线程调用,此时不需要考虑加锁的问题。而对于对象的同步方法来说, 任意时刻有且仅有一个拥有该对象独占锁的线程能够调用它们。 例如,一个同步方法是独占的。如果线程...
  • //调用wait方法,放弃cpu的执行,进入waiting状态 try { obj.wait(); } catch (InterruptedException e) { e.printStackTrace(); } //唤醒之后执行的代码 System.out.println("包子做好了,开吃!"); } } }.start();...
  • Java Object wait()方法

    2021-02-28 10:51:09
    Java Object wait()方法java.lang.Object.wait(long timeout, int nanos...此方法类似于wait方法的一个参数,但它允许更好地控制的时间等待一个通知放弃之前的量。实时量,以毫微秒计算,计算公式如下:1000000*time...
  • 点击关注公众号,实用技术文章及时了解来源:blog.csdn.net/qq_42145871/article/details/81950949先回答问题:(1)为什么wait()必须同步...
  • 2)调用某个对象的wait()方法能让当前线程阻塞,并且当前线程必须拥有此对象的monitor(即锁,或者叫管程)3)调用某个对象的notify()方法能够唤醒一个正在等待这个对象的monitor的线程,如果有多个线程都等待这个对象...
  • 线程通信:不同的线程执行不同的任务,如果这些...2.使用一个或多个线程来表示生产者(Producer)。3.使用一个或多个线程来表示消费者(Consumer)。为什么生产者不直接把数据给消费者,而是先把数据存储到共享资源中,...
  • in object class For this questions sake consider as if wait() and notifyAll() are in thread classJava语言中,对一个对象的特定实例wait() – 一个分配...
  • 首先我们来看看wait方法的源码注释是怎么写的? //wait method should always be used in a loop: synchronized (ojb) { while(condition does not hold) obj.wait(); ... //Perform action appropriate to ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 520,077
精华内容 208,030
关键字:

wait方法在哪里使用