精华内容
下载资源
问答
  • Object的wait()和Condition的await() 1、Object的wait() Object类: 1)源码: public final void wait() throws InterruptedException { wait(0); } 2)解释: Object的wait方法,是当前线程调用...

    1、Object的wait()

    Object类:

    1)源码:

        public final void wait() throws InterruptedException {
            wait(0);
        }
    

    2)解释:

    • Object的wait方法,是当前线程调用synchronized后获取到了对象的锁之后才可以使用
    • 调用wait()让当前线程进入一个waitSet(可以理解为有一个休息室),这样其他等待同一个对象锁的线程有机会获得锁
    • 唤醒对象上等待的线程需要配合notify()或者notifyAll()方法使用

    3)使用示例:

    public class TestWaitNotify {
        final static Object obj = new Object();
    
        public static void main(String[] args) {
    
            new Thread(() -> {
                synchronized (obj) {
                    log.debug("执行....");
                    try {
                        obj.wait(); // 让线程在obj上一直等待下去
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    log.debug("其它代码....");
                }
            },"t1").start();
    
            new Thread(() -> {
                synchronized (obj) {
                    log.debug("执行....");
                    try {
                        obj.wait(); // 让线程在obj上一直等待下去
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    log.debug("其它代码....");
                }
            },"t2").start();
    
            // 主线程两秒后执行
            sleep(0.5);
            log.debug("唤醒 obj 上其它线程");
            synchronized (obj) {
    //            obj.notify(); // 唤醒obj上一个线程
                obj.notifyAll(); // 唤醒obj上所有等待线程
            }
        }
    }
    

    2、Condition的await()

    Condition类:

    1)源码

    void await() throws InterruptedException;
    

    2)解释:

    • Condition类上的wait方法,配合ReentrantLock (可重入锁)使用
    • 调用await()让当前线程进入一个waitSet(可以理解为有一个休息室),这样其他等待同一个对象锁的线程有机会获得锁,这点和object.wait()一致
    • 唤醒对象上等待的线程需要配合signal()或者signalAll()方法使用
    • Condition 相当于lock对象的特定的休息室,可以创建不同的condition,来分别进行等待

    3)使用示例:

        private static ReentrantLock lock = new ReentrantLock();
    
        public static void main(String[] args) throws InterruptedException {
    
            //创建一个新的条件变量(休息室)
            Condition condition = lock.newCondition();
    
            lock.lock();
            //进入休息室等待
            condition.await();
    
            //condition.signal(); //唤醒当前休息室的某个线程
            condition.signalAll(); //唤醒当前休息室的所有线程
    
            lock.unlock();
    
        }
    
    展开全文
  • Object的wait() wait()搭配notify(),nofityAll()使用。 线程获取到对象锁之后,执行wait()就会释放对象锁,同时线程挂起,直到其他线程获取到对象锁并执行notify()后,线程重新开始运行。 final static Object async...

    Object的wait()

    wait()搭配notify(),nofityAll()使用。
    线程获取到对象锁之后,执行wait()就会释放对象锁,同时线程挂起,直到其他线程获取到对象锁并执行notify()后,线程重新开始运行。

    final static Object async = new Object();
    
        public static void main(String[] args) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    synchronized (async) {
                        System.out.println("thread a get async");
                        try {
                            System.out.println("thread a start wait");
                            async.wait();
                            System.out.println("thread a end wait");
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }).start();
    
            new Thread(new Runnable() {
                @Override
                public void run() {
                    synchronized (async){
                        System.out.println("thread b get async");
                        System.out.println("thread b notify async");
                        async.notify();
                    }
                }
            }).start();
        }

    输出:

    thread a get async
    thread a start wait
    thread b get async
    thread b notify async
    thread a end wait

    Thread.sleep()

    线程获取到对象锁之后,sleep时不会释放对象锁,其他线程也不能获取到对象锁。直到线程sleep结束,其他线程才能获取到对象锁。

    final static Object async = new Object();
    
        public static void main(String[] args) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    synchronized (async) {
                        System.out.println("thread a get async");
                        try {
                            System.out.println("thread a start sleep");
                            Thread.sleep(1000);
                            System.out.println("thread a end sleep");
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }).start();
    
            new Thread(new Runnable() {
                @Override
                public void run() {
                    synchronized (async) {
                        System.out.println("thread b get async");
                        System.out.println("thread b notify async");
                        async.notify();
                    }
                }
            }).start();
        }

    输出:

    thread a get async
    thread a start sleep
    thread a end sleep
    thread b get async
    thread b notify async

    转载于:https://www.cnblogs.com/jiy-for-you/p/7282042.html

    展开全文
  • 主要介绍了Java 中Object的wait() notify() notifyAll()方法使用的相关资料,需要的朋友可以参考下
  • 在使用Lock之前,我们都使用Object 的wait和notify实现同步的。举例来说,一个producer和consumer,consumer发现没有东西了,等待,produer生成东西了,唤醒。 线程consumer 线程producer ...

     在使用Lock之前,我们都使用Object 的wait和notify实现同步的。举例来说,一个producer和consumer,consumer发现没有东西了,等待,produer生成东西了,唤醒。

    线程consumer 线程producer
    synchronize(obj){ 
        obj.wait();//没东西了,等待 
    }
    synchronize(obj){ 
        obj.notify();//有东西了,唤醒 
    }

    有了lock后,世道变了,现在是:

    lock.lock(); 
    condition.await(); 
    lock.unlock();
    lock.lock(); 
    condition.signal(); 
    lock.unlock();

    为了突出区别,省略了若干细节。区别有三点:

    1. 1. lock不再用synchronize把同步代码包装起来;
    2. 2. 阻塞需要另外一个对象condition;
    3. 3. 同步和唤醒的对象是condition而不是lock,对应的方法是await和signal,而不是wait和notify。

    为什么需要使用condition呢?简单一句话,lock更灵活。以前的方式只能有一个等待队列,在实际应用时可能需要多个,比如读和写。为了这个灵活性,lock将同步互斥控制和等待队列分离开来,互斥保证在某个时刻只有一个线程访问临界区(lock自己完成),等待队列负责保存被阻塞的线程(condition完成)。

    通过查看ReentrantLock的源代码发现,condition其实是等待队列的一个管理者,condition确保阻塞的对象按顺序被唤醒。

    wait()和notify()必须在synchronized的代码块中使用 因为只有在获取当前对象的锁时才能进行这两个操作 否则会报异常 而await()和signal()一般与Lock()配合使用

    notify和notifyAll有什么区别

    notify():唤醒在此对象监视器上等待的单个线程。
    notifyAll():唤醒在此对象监视器上等待的所有线程。线程通过调用其中一个 wait 方法,在对象的监视器上等待。

    锁池和等待池

    锁池:假设线程A已经拥有了某个对象(注意:不是类)的锁,而其它的线程想要调用这个对象的某个synchronized方法(或者synchronized块),由于这些线程在进入对象的synchronized方法之前必须先获得该对象的锁的拥有权,但是该对象的锁目前正被线程A拥有,所以这些线程就进入了该对象的锁池中。
    等待池:假设一个线程A调用了某个对象的wait()方法,线程A就会释放该对象的锁后,进入到了该对象的等待池中
    所以我们可以很容易看到这两者的区别了:

    如果线程调用了对象的 wait()方法,那么线程便会处于该对象的等待池中,等待池中的线程不会去竞争该对象的锁。
    当有线程调用了对象的 notifyAll()方法(唤醒所有 wait 线程)或 notify()方法(只随机唤醒一个 wait 线程),被唤醒的的线程便会进入该对象的锁池中,锁池中的线程会去竞争该对象锁。也就是说,调用了notify后只要一个线程会由等待池进入锁池,而notifyAll会将该对象等待池内的所有线程移动到锁池中,等待锁竞争
    优先级高的线程竞争到对象锁的概率大,假若某线程没有竞争到该对象锁,它还会留在锁池中,唯有线程再次调用 wait()方法,它才会重新回到等待池中。而竞争到对象锁的线程则继续往下执行,直到执行完了 synchronized 代码块,它会释放掉该对象锁,这时锁池中的线程会继续竞争该对象锁。
    综上,所谓唤醒线程,另一种解释可以说是将线程由等待池移动到锁池,notifyAll调用后,会将全部线程由等待池移到锁池,然后参与锁的竞争,竞争成功则继续执行,如果不成功则留在锁池等待锁被释放后再次参与竞争。而notify只会唤醒一个线程。有了这些理论基础,后面的notify可能会导致死锁,而notifyAll则不会的例子也就好解释了

    转载于:https://www.cnblogs.com/aaron911/p/11043699.html

    展开全文
  • 一、这里先来介绍下object的wait、notify和notify all方法 wait、notify和notifyAll方法是Object类的final native方法。所以这些方法不能被子类重写,Object类是所有类的超类,因此在程序中有以下三种形式调用...

    一、这里先来介绍下object的wait、notify和notify all方法

    wait、notify和notifyAll方法是Object类的final native方法。所以这些方法不能被子类重写,Object类是所有类的超类,因此在程序中有以下三种形式调用wait等方法。

    wait();//方式1:
    this.wait();//方式2:
    super.wait();//方式3

    void notifyAll()

    解除所有那些在该对象上调用wait方法的线程的阻塞状态。该方法只能在同步方法同步块内部调用。如果当前线程不是锁的持有者,该方法抛出一个IllegalMonitorStateException异常。

    void notify()

    随机选择一个在该对象上调用wait方法的线程,解除其阻塞状态。该方法只能在同步方法同步块内部调用。如果当前线程不是锁的持有者,该方法抛出一个IllegalMonitorStateException异常。

    void wait()

    导致线程进入等待状态,直到它被其他线程通过notify()或者notifyAll唤醒。该方法只能在同步方法中调用。如果当前线程不是锁的持有者,该方法抛出一个IllegalMonitorStateException异常。

    void wait(long millis)和void wait(long millis,int nanos)

    导致线程进入等待状态直到它被通知或者经过指定的时间。这些方法只能在同步方法中调用。如果当前线程不是锁的持有者,该方法抛出一个IllegalMonitorStateException异常。

    Object.wait()和Object.notify()和Object.notifyall()必须写在synchronized方法内部或者synchronized块内部,这是因为:这几个方法要求当前正在运行object.wait()方法的线程拥有object的对象锁。即使你确实知道当前上下文线程确实拥有了对象锁,也不能将object.wait()这样的语句写在当前上下文中。

    二、讲一下这两者之间的差别

    1、这两个方法来自不同的类分别是,sleep来自Thread类,和wait来自Object类。

    sleep是Thread的静态类方法,谁调用的谁去睡觉,即使在a线程里调用了b的sleep方法,实际上还是a去睡觉,要让b线程睡觉要在b的代码中调用sleep。

    2、最主要sleep方法没有释放锁,而wait方法释放了锁,使得其他线程可以使用同步控制块或者方法。

    sleep不出让系统资源;wait是进入线程等待池等待,出让系统资源,其他线程可以占用CPU。一般wait不会加时间限制,因为如果wait线程的运行资源不够,再出来也没用,要等待其他线程调用notify/notifyAll唤醒等待池中的所有线程,才会进入就绪队列等待OS分配系统资源。sleep(milliseconds)可以用时间指定使它自动唤醒过来,如果时间不到只能调用interrupt()强行打断。

    Thread.Sleep(0)的作用是“触发操作系统立刻重新进行一次CPU竞争”。

    3、使用范围:wait,notify和notifyAll只能在同步控制方法或者同步控制块里面使用,而sleep可以在任何地方使用 
       synchronized(x){ 
          x.notify() 
         //或者wait() 
       }

    4、sleep必须捕获异常,而wait,notify和notifyAll不需要捕获异常

    展开全文
  • Object的wait和notify实现生产者和消费者 public class ConsumerAndProducer { private int queueSize = 10; private PriorityQueue<Integer> queue = new PriorityQueue<>...
  • 在使用Lock之前,我们都使用Object 的wait和notify实现同步的。举例来说,一个producer和consumer,consumer发现没有东西了,等待,producer生成东西了,唤醒。 线程consumer 线程producer ...
  • 在使用Lock之前,我们都使用Object 的wait和notify实现同步的。举例来说,一个producer和consumer,consumer发现没有东西了,等待,produer生成东西了,唤醒。 线程consumer 线程producer synchronize...
  • java中所有的类都会隐式的继承Object,但是Object的wait,notify,notifyAll我们又真的会用吗 synchronized synchronized是用来保证我们的一段代码在执行的过程中不会被中断而引起并发问题,synchronized可以修饰一个...
  • 1.wait方法 This method should only be called by a thread that is the owner * of this object’s monitor. See the {@code notify} method for a * description of the ways in which a thread can become the ...
  • Java 中Object的wait() notify() notifyAll()方法使用一、前言对于并发编程而言,除了Thread以外,对Object对象的wati和notify对象也应该深入了解其用法,虽然知识点不多。二、线程安全基本知识首先应该记住以下基本...
  • 在使用Lock之前,我们都使用Object 的wait和notify实现同步的。举例来说,一个producer和consumer,consumer发现没有东西了,等待,produer生成东西了,唤醒。 线程consumer 线程producer synchronize(obj){ ...
  • Java中的Object的Wait() 和notify()方法使用时应注意的地方和Thread中的sleep()方法 1)sleep 是线程类(Thread)的方法,导致此线程暂停执行指定时间,给执行机会给其他线程,但是监控状态依然保持,...
  • 关于object的wait和notity

    2017-02-08 18:18:00
    起初想测试下,object的notifyAll和notify方法,关于notifyAll和notify,jdk的说明文档已经讲的很清楚了,这里再说明下 notifyAll是唤醒在该对象上所有等待该对象monitor的线程。关于monitor,其实还是有些说法的,...
  • 1、wait可以让当前线程释放持有锁,并让线程处于wait状态 2、notify随机唤醒之前持有该锁对象处于wait状态线程,让其加入锁竞争(不会马上获得锁) 3、notifyAll唤醒所有之前持有该锁对象处于wait状态...
  • waitObject方法,对此对象调用wait 方法导致本线程放弃对象锁,进入等待此对象等待锁定池,只有针对此对象发出notify 方法(或notifyAll)后本线程才进入对象锁定池准备获得对象锁进入运行状态。1、这...
  • 两者都是Object方法。 wait() 使用时候必须注意在 synchronized 代码块里执行。 因为执行 wait 函数之前会先获取到目标对象监视器,然后释放监视器,方便其他等待在这个目标对象上线程可以继续执行下去...
  • 概述 wait和notify是用于线程间通信。...一般wait的用法如下 while(queue.size() == MAX_SIZE){ wait() } 假如不对这段代码加锁,就会出现问题。模拟一个生产者线程t1和一个消费者线程t2,例子如下 t...
  • 认识Object.wait()方法:   导致当前线程等待,直到该对象notify或notifyAll被执行。换句话说,这个方法行为效果完全与简单调用wait(0)一样。当前线程必须拥有对象监视器。线程释放对象监视器所有权,等待直到...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 8,421
精华内容 3,368
关键字:

object的wait