Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

2019-07-23:Java 线程中notify 和 notifyAll有什么区别? #104

Open
MoJieBlog opened this issue Jul 23, 2019 · 7 comments
Open

2019-07-23:Java 线程中notify 和 notifyAll有什么区别? #104

MoJieBlog opened this issue Jul 23, 2019 · 7 comments
Labels

Comments

@MoJieBlog
Copy link
Collaborator

No description provided.

@yangfanggang
Copy link

notify 和 notifyAll是object的方法

当线程状态为等待、超时等待会调用notify 和 notifyAll方法通知线程更改状态,此时
当线程数量为1时,notify 和 notifyAll的效果一样,会唤醒一个线程,并获取锁
当线程数量大于1时,notify会唤醒一个线程,并获取锁,notifyAll会唤醒所有线程并根据算法选取其中一个线程获取锁,区别在于此时使用notify可能会出现死锁的情况

具体解释
Object的notify和notifyAll方法的区别

@gabyallen
Copy link

notify方法
1.方法调用之前由于也需要获取该对象的锁,所以使用的位置: synchronized方法中或者synchronized代码块中
2.通知那些可能等待该对象的对象锁的其他线程。如果有多个线程等待,则线程规划器任意挑选出其中一个wait()状态的线程来发出通知
3.wait()方法执行完毕之后,会立刻释放掉锁,如果没有再次使用notify,其他wait()的线程由于没有得到通知,会继续阻塞在wait()的状态,等待其他对象调用notify或者notifyAll来唤醒。
notifyAll方法
1.使用位置和notify一样
2.notifyAll唤醒所有处于wait的线程

@18361237136
Copy link

当线程处于等待、超时等待的时候会调用notify和notifyAll通知线程更改状态,当只有一个线程的时候,这两个效果一样,会唤醒一个线程并获取锁。当线程数量大于1的时候notify会唤醒一个线程,nitifyAll会唤醒所有线程并选取其中一个线程获取锁。

@suagger
Copy link

suagger commented Nov 14, 2019

notify和notifyall都是object的方法
当线程处于等待状态,超时等待的时候会调用notify和notufyAll通知线程更改状态,当只有一个线程的时候,两个方法的效果是一样的,当有多个线程的时候,notify会选择唤醒一个线程获取锁,notifyall会唤醒所有的线程,让它们从等待池都进入到该对象的锁池,然后其中一个线程竞争获取锁

@chunlinchulv
Copy link

notify、notifyAll和wait()是Java同步机制中的重要组成部分,与synchronized关键字结合使用。
在使用wait()方法使线程处于等待状态时,有两种情况:1.只有一个线程处于等待状态,这时候可以调用notify或者notifyAll方法使当先线程恢复原来的状态。2.有多个线程处于等待状态,调用notify方法会随机唤醒一个线程(线程优先级高的线程被唤醒的几率更大),调用notifyAll方法会唤醒所有的线程。

@syx103
Copy link

syx103 commented Nov 17, 2019

两者都是将等待线程中的线程调动至锁池,竞争锁对象,获得执行权,notify()是将等待池中的任意一个调至锁池,与锁池中的其他线程争夺锁对象,notifyAll()是将等待池中的全部线程调至锁池中。前者一般适用于仅有一个线程有效执行的情况,后者一般作用在全部。

@senlinxuefeng
Copy link

区别
notify:只会唤醒等待该锁的其中一个线程。
notifyAll:唤醒等待该锁的所有线程。
既然notify会唤醒一个线程,并获取锁,notifyAll会唤醒所有线程并根据算法选取其中一个线程获取锁,那最终结果不都是只有一个线程获取锁吗?那JDK为什么还需要做出来这两个方法呢?这两种同步方法本质上会有什么区别?

这还要从对象内部锁的调度说起。

对象内部锁
其实,每个对象都拥有两个池,分别为锁池(EntrySet)和(WaitSet)等待池。

锁池:假如已经有线程A获取到了锁,这时候又有线程B需要获取这把锁(比如需要调用synchronized修饰的方法或者需要执行synchronized修饰的代码块),由于该锁已经被占用,所以线程B只能等待这把锁,这时候线程B将会进入这把锁的锁池。
等待池:假设线程A获取到锁之后,由于一些条件的不满足(例如生产者消费者模式中生产者获取到锁,然后判断队列为满),此时需要调用对象锁的wait方法,那么线程A将放弃这把锁,并进入这把锁的等待池。
如果有其他线程调用了锁的notify方法,则会根据一定的算法从等待池中选取一个线程,将此线程放入锁池。
如果有其他线程调用了锁的notifyAll方法,则会将等待池中所有线程全部放入锁池,并争抢锁。

锁池与等待池的区别:等待池中的线程不能获取锁,而是需要被唤醒进入锁池,才有获取到锁的机会。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

9 participants