当前位置:首页 » 编程语言 » java线程的唤醒

java线程的唤醒

发布时间: 2022-11-05 00:01:08

java 多线程子线程唤醒主线程问题

设一个三个线程的共享对象o

a.start(); b.start();//启动子线程
主线程中
o.wait(10*1000);//主线程中等10秒
同时A、B中各有一个执行完的通知
a或b的run(){
.....
o. notify();
}
基本的线程操作...

Ⅱ java 线程 唤醒问题

首先,从你程序的本意来看, 你是想用线程实现一个生产者-- 消费者模式, 用在馒头的场景, 如下:

1、 肯定需要一个篮子, 负责装馒头,并且这个篮子有容量,假设容量为C;
2、 有两个人,第一个是爹(生产者), 第二个是娃(消费者), 爹负责向篮子中放入馒头, 娃负责从篮子中取出馒头喂狗;
3、 但是篮子的容量是有限的, 当篮子被装满时, 爹就等待娃从篮子中取出馒头,篮子腾出空间之后,爹继续装馒头; 当篮子的馒头都被取走后, 娃就等待, 当篮子中又被放入馒头时,才继续取馒头。

附上代码:

篮子:

public class Bucket {
private int count = 0; // 篮子能够容纳的馒头数
private int total = 0; // 放馒头的总数

public synchronized void put(){
if(count == 5){
try {
System.out.println("俺是他爹,篮子满了,俺在等俺家娃拿馒头喂狗");
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}

count += 1;
total++;
System.out.println("俺是他爹,俺放了一个馒头,现有篮子里有 [" + count + "] 个馒头");
notify();
}

public synchronized boolean get(){
if(count == 0){
try {
wait();
System.out.println("俺是他娃,篮子空了,俺在等俺爹放馒头到篮子里");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
count -= 1;
System.out.println("俺拿了一个馒头喂俺家大花狗, 篮子里还有 [" + count + "] 个馒头");
notify();

if(total == 100 && count == 0){
return false;
}else{
return true;
}
}

爹:

public class Proct implements Runnable{

private Bucket bucket;
Proct(Bucket bucket){
this.bucket = bucket;
}

@Override
public void run() {
for(int i=0; i<100; i++){
bucket.put();
}
System.out.println("俺把馒头都放完了");
}
}

娃:

public class Consumer implements Runnable{

private Bucket bucket;
public Consumer(Bucket bucket){
this.bucket = bucket;
}

@Override
public void run() {
while(true){
if(!bucket.get()){
break;
}
}
System.out.println("俺家大花狗吃完馒头了");
}

}

启动类:

public class Test {

public static void main(String[] args) {

Bucket bucket = new Bucket();
new Thread(new Consumer(bucket)).start();
new Thread(new Proct(bucket)).start();
}
}

最后附上你的问题, notify 由谁来唤醒:

注意 wait() 和 notify() 是Object类上的方法,
notify() 的意思是: 从加锁的对象的监视器(监视器就是锁)的等待队列中, 任意取出一个等待线程, 让该线程处于runnable状态;
wait()的意思是: 把锁住对象的当前线程, 放入到监视器的等待队列中。

所以,notify()的意思就是要唤醒等待队列中的一个等待线程,当程序发起这么一个事件后, 是由虚拟机的线程调度器完成线程状态之间的转换的。

Ⅲ java的等待唤醒机制必须要让线程等待吗

1. 线程的挂起和唤醒
挂起实际上是让线程进入“非可执行”状态下,在这个状态下CPU不会分给线程时间片,进入这个状态可以用来暂停一个线程的运行;在线程挂起后,可以通过重新唤醒线程来使之恢复运行。

挂起的原因可能是如下几种情况:
(1)通过调用sleep()方法使线程进入休眠状态,线程在指定时间内不会运行。
(2)通过调用join()方法使线程挂起,使自己等待另一个线程的结果,直到另一个线程执行完毕为止。
(3)通过调用wait()方法使线程挂起,直到线程得到了notify()和notifyAll()消息,线程才会进入“可执行”状态。
(4)使用suspend挂起线程后,可以通过resume方法唤醒线程。
虽然suspend和resume可以很方便地使线程挂起和唤醒,但由于使用这两个方法可能会造成死锁,因此,这两个方法被标识为deprecated(抗议)标记,这表明在以后的jdk版本中这两个方法可能被删除,所以尽量不要使用这两个方法来操作线程。

调用sleep()、yield()、suspend()的时候并没有被释放锁
调用wait()的时候释放当前对象的锁

wait()方法表示,放弃当前对资源的占有权,一直等到有线程通知,才会运行后面的代码。
notify()方法表示,当前的线程已经放弃对资源的占有,通知等待的线程来获得对资源的占有权,但是只有一个线程能够从wait状态中恢复,然后继续运行wait()后面的语句。
notifyAll()方法表示,当前的线程已经放弃对资源的占有,通知所有的等待线程从wait()方法后的语句开始运行。

2.等待和锁实现资源竞争
等待机制与锁机制是密切关联的,对于需要竞争的资源,首先用synchronized确保这段代码只能一个线程执行,可以再设置一个标志位condition判断该资源是否准备好,如果没有,则该线程释放锁,自己进入等待状态,直到接收到notify,程序从wait处继续向下执行。

synchronized(obj) {
while(!condition) {
obj.wait();
}
obj.doSomething();
}

以上程序表示只有一个线程A获得了obj锁后,发现条件condition不满足,无法继续下一处理,于是线程A释放该锁,进入wait()。

在另一线程B中,如果B更改了某些条件,使得线程A的condition条件满足了,就可以唤醒线程A:

synchronized(obj) {
condition = true;
obj.notify();
}

需要注意的是:
# 调用obj的wait(), notify()方法前,必须获得obj锁,也就是必须写在synchronized(obj) {...} 代码段内。
# 调用obj.wait()后,线程A就释放了obj的锁,否则线程B无法获得obj锁,也就无法在synchronized(obj) {...} 代码段内唤醒A。
# 当obj.wait()方法返回后,线程A需要再次获得obj锁,才能继续执行。
# 如果A1,A2,A3都在obj.wait(),则B调用obj.notify()只能唤醒A1,A2,A3中的一个(具体哪一个由JVM决定)。
# obj.notifyAll()则能全部唤醒A1,A2,A3,但是要继续执行obj.wait()的下一条语句,必须获得obj锁,因此,A1,A2,A3只有一个有机会获得锁继续执行,例如A1,其余的需要等待A1释放obj锁之后才能继续执行。
# 当B调用obj.notify/notifyAll的时候,B正持有obj锁,因此,A1,A2,A3虽被唤醒,但是仍无法获得obj锁。直到B退出synchronized块,释放obj锁后,A1,A2,A3中的一个才有机会获得锁继续执行。

Ⅳ java中如何线程的睡眠与唤醒

classMyThreadextendsThread
{
publicMyThread()
{
super();
}
publicMyThread(Stringname)
{
super(name);
}
publicvoidrun()
{
for(inti=0;i<10;i++)
{
System.out.println(super.getName()+":"+i);
try
{
sleep(500);
}
catch(InterruptedExceptione)
{
System.out.println("线程被叫醒");
}
}
}
}
publicclassSleepTest
{
publicstaticvoidmain(String[]args)
{
MyThreadthread1=newMyThread("第1个线程");
MyThreadthread2=newMyThread("第2个线程");
thread1.start();
thread2.start();
}
}

Ⅳ java线程中怎么唤醒被wait的线程

notify()方法
无法指定。选择是任意性的。
唤醒在此对象监视器上等待的单个线程。如果有多个线程都在此对象上等待,则会选择唤醒其中一个线程。

Ⅵ java 多线程子线程唤醒主线程问题

设一个三个线程的共享对象o
a.start();
b.start();//启动子线程
主线程中
o.wait(10*1000);//主线程中等10秒
同时A、B中各有一个执行完的通知
a或b的run(){
.....
o.
notify();
}
基本的线程操作...

Ⅶ java如何唤醒指定的等待线程

notify()方法
无法指定。选择是任意性的。
唤醒在此对象监视器上等待的单个线程。如果有多个线程都在此对象上等待,则会选择唤醒其中一个线程。

Ⅷ java 怎么唤醒一个制定的线程呢

当没有其他线程执行的时候睡眠结束的线程自动运行吧。

Ⅸ java 线程 唤醒等待问题

synchronized(this)
{
notify();
}
所以唤醒的是自己吧?
正确的做法是
thread2
在某个锁上
wait,另外,在绝大多数情况下都把
notify
换成
notifyAll。因为
notify
一次只唤醒一个,多数情况下我们是根据条件来唤醒的。
Object
lock
=
new
Object();
//
线程2
lock.wait();
//
线程1
lock.notifyAll();

热点内容
windows配置ftp 发布:2025-01-11 00:35:02 浏览:656
des算法代码c 发布:2025-01-11 00:33:42 浏览:805
共享文件夹设置密码无法访问 发布:2025-01-11 00:32:49 浏览:478
槽钢算法 发布:2025-01-11 00:26:21 浏览:883
linux命令包 发布:2025-01-10 23:54:26 浏览:32
python轮廓 发布:2025-01-10 23:49:23 浏览:178
思科配置线怎么选 发布:2025-01-10 23:48:44 浏览:704
解压水晶泥 发布:2025-01-10 23:27:23 浏览:634
小米摄像头如何改wifi密码 发布:2025-01-10 23:25:14 浏览:115
阿里云服务器首页 发布:2025-01-10 23:24:15 浏览:436