精华内容
下载资源
问答
  • 为什么Wait和notify方法Object中?

    千次阅读 2020-11-27 09:05:28
    ** 为什么Wait和notify方法Object类中** 为何 wait,notify 和 notifyAll 属于 Object 类? 为什么它们不应该在 Thread 类中? 以下观点我认为有道理的: wait 和 notify 不仅仅普通方法或同步工具,更重要的...

    为什么Wait和notify方法在Object类中
    为何 wait,notify 和 notifyAll 属于 Object 类? 为什么它们不应该在 Thread 类中? 以下观点我认为是有道理的:

    1. wait 和 notify 不仅仅是普通方法或同步工具,更重要的是它们是 Java 中两个线程之间的通信机制。
      对语言设计者而言, 如果不能通过 Java 关键字(例如 synchronized)实现通信此机制,同时又要确保这个机制对每个对象可用, 那么 Object 类则是的合理的声明位置。
      记住同步和等待通知是两个不同的领域,不要把它们看成是相同的或相关的。同步是提供互斥并确保 Java 类的线程安全,而 wait 和 notify 是两个线程之间的通信机制。
    2. 每个对象都可上锁,这是在 Object 类而不是 Thread 类中声明 wait 和 notify 的另一个原因。
    3. 在 Java 中,为了进入代码的临界区,线程需要锁定并等待锁,他们不知道哪些线程持有锁,而只是知道锁被某个线程持有, 并且需要等待以取得锁, 而不是去了解哪个线程在同步块内,并请求它们释放锁。
    4. Java 是基于 Hoare 的监视器的思想:在Java中,所有对象都有一个监视器。线程在监视器上等待,为执行等待,我们需要2个参数:
      一个线程
      一个监视器(任何对象)
      在 Java 设计中,线程不能被指定,它总是运行当前代码的线程。但是,我们可以指定监视器(这是我们称之为等待的对象)。
      这是一个很好的设计,因为如果我们可以让任何其他线程在所需的监视器上等待,这将导致“入侵”,影响线程执行顺序,导致在设计并发程序时会遇到困难。
      请记住,在 Java 中,所有在另一个线程的执行中造成入侵的操作都被弃用了(例如 Thread.stop 方法)。
    展开全文
  • 在 Java 里面, wait() 和 notify() Object 的成员函数,基础中的基础。为什么Java 要把 wait() 和 notiry() 放在如此基础的类里面,而不作为 Thread 类的成员函数,或者其他类的函数呢? 在回答这个问题之前...

    1、为什么必须和 synchronized 一起使用

    在 Java 里面, wait() 和 notify() 是 Object 的成员函数,是基础中的基础。为什么Java 要把 wait() 和 notiry() 放在如此基础的类里面,而不作为 Thread 类的成员函数,或者其他类的函数呢?

    在回答这个问题之前,我们先聊聊 为什么 wait() 和 notify() 必须和 synchronized 一起使用?看下面代码:

    public class SynchronizedDemo3 {
    
    	private Object lock = new Object();
    
    	public void increment() {
    		synchronized (lock) {
    			// do something
    			lock.wait();
    			// do something
    
    		}
    	}
    
    	public void decrement() {
    		synchronized (lock) {
    			// do something
    			lock.notify();
    			// do something
    		}
    	}
    }

     我们启动两个线程 A,B,线程A 调用 increment() 方法,线程B 调用 decrement() 方法。很显然,两个线程之间要通信,对于同一个对象来说,一个线程调用该对象的 wait()方法,另个线程调用该对象的 notify() 方法,该对象本身就要互斥!所有,在调用 wait() 和 notify() 方法之前,需要通过 synchronized 关键字给对象 lock 加锁。

    我们都知道,synchronized 关键字可以加在任何对象的成员函数上,任何对象也都可以成为锁。那么,wait() 和 notify() 这样普及,Object 又是所有类的基类,那么 wait() 和 notify() 放在Object 里面最合适不过了。

    2、为什么 wait() 的时候必须释放锁

    根据上面的代码,当线程A 进入 synchronized(lock)代码块后,也就是对 lock 上了锁,此时,调用wait() 进入阻塞状态,一直不能退出 synchronized 代码块;那么线程B 永远无法进入 synchronized(lock)   代码块里,也就永远没有机会调用 notify(),这岂不就死锁了?

    这就涉及一个关键的问题,在wait() 的内部,需要先释放锁lock,然后进入阻塞状态,之后,线程B 可以再持有这个锁,也就能够调用 notify() 方法唤醒线程A,然后,线程A再次 获取锁,继续执行后续代码逻辑,执行完后退出 synchronized 代码块,再次释放锁。

    只有如此,才能避免死锁的可能。

    3、wait() 与 notify() 的问题

    因为 notify() 一次只能唤醒一个线程,如在多生产者-多消费者模式中,如果生产者 想唤醒的是消费者,但有可能唤醒的是生产者, 消费者想唤醒生产者,也有可能把消费者唤醒了。所有在wait() 时最好使用 notifyAll() 唤醒所有的线程,去抢锁。在J.U.C 并发包中 Lock 和Condition 配合可以完美的解决此问题。

    4、总结

    本篇文章主要介绍了,wait()、notify()和notifyAll() 方法为什么在Object 类中,和在调用 wait()方法后为什么需要释放锁。只要掌握了 synchronized 关键字加锁本质以及线程的互斥与同步的原理,就不难理解这些。

     

     

    展开全文
  • wait和notify用于线程间通信。 以生产者消费者模式来说的话,就是生产者和消费者通过队列进行通信,既然他们通过同一个队列通信,那么对于队列的操作就一定要保证线程安全性。 代码解释 一般wait的用法如下 while...

    概述

    wait和notify是用于线程间通信。
    以生产者消费者模式来说的话,就是生产者和消费者通过队列进行通信,既然他们通过同一个队列通信,那么对于队列的操作就一定要保证线程安全性。

    代码解释

    一般wait的用法如下

    while(queue.size() == MAX_SIZE){
    	wait()
    }
    

    假如不对这段代码加锁,就会出现问题。模拟一个生产者线程t1和一个消费者线程t2,例子如下

    • t1判断队列满,需要wait阻塞线程。
    • 但是就在t1还没有调用wait的时候,消费者t2消费了一个产品,导致队列非满。
    • 这时候生产者线程t1调用wait阻塞,造成的情况就是队列非满,但是生产者线程阻塞了。
    • 假如此时消费者不消费了,那么生产者则会一直阻塞下去。。。出现老问题!!!

    所以在调用wait和notify以及notifyAll等方法时一定要进行同步处理。

    温馨提示

    • 如果您对本文有疑问,请在评论部分留言,我会在最短时间回复。
    • 如果本文帮助了您,也请评论,作为对我的一份鼓励。
    • 如果您感觉我写的有问题,也请批评指正,我会尽量修改。
    展开全文
  • wait()、notify()和notifyAll()方法为什么属于Object

    千次阅读 热门讨论 2019-01-27 15:59:37
    要搞清这个问题,我们首先需要知道wait()、notify()和notifyAll()干吗的,然后才能够知道它们为什么属于Object。就以wait为例吧,wait的含义使当前线程放弃对象锁,并进入阻塞状态。 原因 原因一:Java中,...

    前提条件

    要搞清这个问题,我们首先需要知道wait()、notify()和notifyAll()是干吗的,然后才能够知道它们为什么属于Object。就以wait为例吧,wait的含义是使当前线程放弃对象锁,并进入阻塞状态。

    原因

    • 原因一:Java中,任何对象都可以作为锁,既然wait是放弃对象锁,当然就要把wait定义在这个对象所属的类中。更通用一些,由于所有类都继承于Object,我们完全可以把wait方法定义在Object类中,这样,当我们定义一个新类,并需要以它的一个对象作为锁时,不需要我们再重新定义wait方法的实现,而是直接调用父类的wait(也就是Object的wait),此处,用到了Java的继承。
    • 原因二:有的人会说,既然是线程放弃对象锁,那也可以把wait定义在Thread类里面啊,新定义的线程继承于Thread类,也不需要重新定义wait方法的实现。然而,这样做有一个非常大的问题,一个线程完全可以持有很多锁,你一个线程放弃锁的时候,到底要放弃哪个锁?当然了,这种设计并不是不能实现,只是管理起来更加复杂。

    综上所述,wait()、notify()和notifyAll()方法要定义在Object类中。

    温馨提示

    • 如果您对本文有疑问,请在评论部分留言,我会在最短时间回复。
    • 如果本文帮助了您,也请评论,作为对我的一份鼓励。
    • 如果您感觉我写的有问题,也请批评指正,我会尽量修改。
    展开全文
  • 1.wait()、notify()和notifyAll()方法是本地方法,并且final方法,无法被重写。 2.调用某个对象的wait()方法能让当前线程阻塞,并且当前线程必须拥有此对象的monitor(锁)。 3.调用某个对象的notify()方法能够...
  • 为什么wait,notify,notifyAll声明在类Object中而不是在Thread中这个问题一个非常有名的java核心面试题,在各种级别的Java开发者面试中都会出现
  • 5.为什么wait(),notify(),notifyAll()等方法定义在Object类中 因为这些方法的调用依赖锁对象,而同步代码块的锁对象任意锁 而Object代码任意的对象,所以,定义在这里面。
  • 一、基础篇--1.1Java基础-Object类中常见的方法为什么wait notify会放在Object里边 这个设计相关的问题,它考察的面试者对现有系统和一些普遍存在但看起来不合理的事物的看法。回答这些问题的...
  • 点击上方“芋道源码”,选择“设星标”管她前浪,还是后浪?能浪的浪,才好浪!每天 8:55 更新文章,每天掉亿点点头发...源码精品专栏原创 | Java 2020 超神之路,很肝~...
  • 为什么wait/notify/notifyAll被定义在Object类中,而sleep定义在Thread类中 因为java中每个对象都有一把称之为monitor监控器的锁 由于每个对象都可以上锁,这就要求在对象头中有一个用来保存锁信息的位置 这个锁...
  • 回答这些问题的时候,你要说明为什么把这些方法放在Object类里有意义的,还有不把它放在Thread类里的原因。一个很明显的原因JAVA提供的锁对象级的而不是线程级的,每个对象都有锁,通过线程获得。如果线程需要...
  • 一个较难回答的 Java 问题, Java 编程语言又不是你设计的,你如何回答这个问题呢? 需要对 Java 编程的常识进行...为什么Object 类中定义 wait 和 notify 方法,每个人都能说出一些理由。 从我的面试经验来看, wait
  • 它们在有 synchronized 标记的方法或 synchronized 块中调用的,因为 wait 和 nodify 需要监视对其调用的 Object。 大多数Java开发人员都知道对象类的 wait(),notify() 和 notifyAll() 方法必须在 Java 中的 ...
  • 这个东西我今天看多线程通信的时候无意中想到的,为什么wait()、notify()、notifyAll()之类的线程间通信需要放在同步块中,换言之为什么要用synchronized。如果wait()方法不在同步块中,会怎么样嘞: @Test ...
  • 1) wait 和 notify 不仅仅普通方法或同步工具,更重要的它们 Java 中两个线程之间的通信机制。对语言设计者而言, 如果不能通过 Java 关键字(例如 synchronized)实现通信此机制,同时又要确保这个机制对每个...
  • 回顾一下,如果wait()方法不在同步块中,代码的确会抛出异常:public classWaitInSyncBlockTest {@Testpublic voidtest() {try{newObject().wait();}catch(InterruptedException e) {e.printStackTrace();}}}结果:...
  • 为什么wait与notify设计在Object类中?

    千次阅读 2019-02-12 10:47:52
    因为synchronized关键词(设计的初衷可能为了简化多线程程序的编写)可以加在每个类的方法之上。 每个对象都有一个monitor(因此每个对象都潜在需要线程同步),虚拟机在执行synchronized修饰的代码块时,需要...
  • 它们在有 synchronized标记的...大多数Java开发人员都知道对象类的 wait(),notify() 和 notifyAll() 方法必须在 Java 中的 synchronized方法或 synchronized块中调用, 但是我们想过多少次, 为什么在 Java 中 wai...
  • 引言这个东西我今天看多线程通信的时候无意中想到的,为什么wait()、notify()、notifyAll()之类的线程间通信需要放在同步块种,换言之为什么要用synchronized。jie如果wait()方法不在同步块中,会怎么样嘞:@...
  • 首先,如果在未持有对象锁的情况...其次,为什么要这么设计?其实这一种安全设计,为了防止wait错过notify。请看下面代码: boolean wakeuped = false; void dowait() { if(wakeuped) return; wait(); ...
  • 一般基础点的都会问使用的方法,当然这只是初级的问题,那么稍微深点的问题,可能就像我们标题这样:为什么线程通信的方法wait()、notify()、notifyAll()被定义在Object类里面?而sleep定义在Thread类里面? 其实...
  • 1、sleep和wait方法的要点sleep方法保持对象锁,直到它被中断或其时间到期。但是,wait方法释放对调用它的对象锁,并其他对象提供运行的机会。 2、sleep方法属于Thread类,而wait方法属于Object类。 3、sleep...
  • 这些方法存在于同步中;... Condition在java 1.5中才出现的,它用来替代传统的Objectwait()、notify()实现线程间的协作,相比使用Objectwait()、notify(),使用Condition1的await()、signal()这...
  • 这些方法存在于同步中;... Condition在java 1.5中才出现的,它用来替代传统的Objectwait()、notify()实现线程间的协作,相比使用Objectwait()、notify(),使用Condition1的await()、signal()这...

空空如也

空空如也

1 2 3 4 5 ... 18
收藏数 347
精华内容 138
关键字:

为什么wait是object方法