java线程的wait
『壹』 java里多线程的wait问题
喜欢思考绝对是好事,但我希望你对于一个为题你能自己分析的透彻点,wait()当然是线程去等待,线程讲的就是电脑的cpu如何工作,而你说的资源了只是数据也就是你给电脑的一种指令,数据有什么等待的说法吗?还有你说上面的那个程序不会出来,你那个while的条件是什么,你都没吧,如果是死循环那当然不会出来了。
『贰』 新手问个Java中线程wait方法的一个问题
负责任的告诉你 是 主线程在等待。
看 API wait():
在其他线程调用此对象的 notify() 方法或 notifyAll()
方法前,导致当前线程等待。换句话说,此方法的行为就好像它仅执行 wait(0) 调用一样。
当前线程必须拥有此对象监视器。该线程发布对此监视器的所有权并等待,直到其他线程通过调用 notify 方法,或
notifyAll 方法通知在此对象的监视器上等待的线程醒来。然后该线程将等到重新获得对监视器的所有权后才能继续执行。
API 已经很明确说了,导致当前线程等待。
『叁』 Java多线程中await和wait的区别
调用await/wait的时候却释放了其获取的锁并阻塞等待。
await/wait,它会一直阻塞在条件队列之上,之后某个线程调用对应的notify/signal方法,才会使得await/wait的线程回到就绪状态,也是不一定立即执行。
await/wait方法必须放在同步块里面,否则会产生运行时异常。
wait方法是Object类的,await方法是Condition显示条件队列的。
『肆』 java如何停止一个wait的线程
java.lang.System类
staticvoidexit(intstatus)
终止当前正在运行的Java虚拟机。
『伍』 谁能帮我解释一下java线程中的wait()方法的作用与执行原理非常感谢!
wait()方法是java.lang.Object类韦线程提供的用于实现线程间通信的同步控制方法。wait()方法使当前线程主动释放互斥锁,并进入该互斥锁的等待队列。(也就是说,它使当前线程暂停执行,等待其他线程执行notify()方法或者notifyall()方法后再继续执行本线程。)本方法用于释放一个项目的线程,唤醒另一个可能在等待的线程。有两种调用格式:
1.wait()等待通信线程唤醒后再继续执行本线程。
2.wait(long millis)等待通信线程唤醒或者最多等待millis毫秒后,再继续执行本线程。
我知道的就这么多了哈,希望对你能有一点帮助哦~~
『陆』 java里 对线程的wait方法只有在synchronized下才有用吗
调用 a.wait() 前需要拿到这个 a 对象的锁,这是必须的,像下面这样:
Listqueue=newjava.util.LinkedList();
synchronized(queue){
queue.wait();
}
或者在方法上加了 synchronized,然后用对象自己的锁来等待:
publicsynchronizedbooleanget(){
if(queue.isEmpty()){
this.wait();
}
returnqueue.removeFirst();
}
『柒』 Java线程中wait状态和block状态的区别
一、线程5种状态
新建状态(New) 新创建了一个线程对象。
就绪状态(Runnable) 线程对象创建后,其他线程调用了该对象的start()方法。该状态的线程位于可运行线程池中,变得可运行,等待获取CPU的使用权。
运行状态(Running) 就绪状态的线程获取了CPU,执行程序代码。
阻塞状态(Blocked) 阻塞状态是线程因为某种原因放弃CPU使用权,暂时停止运行。直到线程进入就绪状态,才有机会转到运行状态。阻塞的情况分三种:
等待阻塞:运行的线程执行wait()方法,JVM会把该线程放入等待池中。
同步阻塞:运行的线程在获取对象的同步锁时,若该同步锁被别的线程占用,则JVM会把该线程放入锁池中。
其他阻塞:运行的线程执行sleep()或join()方法,或者发出了I/O请求时,JVM会把该线程置为阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。
死亡状态(Dead):线程执行完了或者因异常退出了run()方法,该线程结束生命周期。
二、Jstack中常见的线程状态
应用程序启动后,我们对系统运行状况的观测大部分情况下是通过运行日志。但是若某一天发现,日志中记录的行为与预想的不一致,此时需要进一步的系统监控该怎么办,Jstack是常用的排查工具,它能输出在某一个时间,Java进程中所有线程的状态,很多时候这些状态信息能给我们的排查工作带来有用的线索。 Jstack的输出中,Java线程状态主要是以下几种:
RUNNABLE 线程运行中或I/O等待
BLOCKED 线程在等待monitor锁(synchronized关键字)
TIMED_WAITING 线程在等待唤醒,但设置了时限
WAITING 线程在无限等待唤醒
1) 让线程一直处于RUNNABLE
public static void runnable() { long i = 0; while (true) { i++; } }
2) 让线程一直处于BLOCKED
public static void blocked() { final Object lock = new Object(); new Thread() { public void run() { synchronized (lock) { System.out.println("i got lock, but don't release"); try { Thread.sleep(1000L * 1000); } catch (InterruptedException e) { } } } }.start(); try { Thread.sleep(100); } catch (InterruptedException e) {} synchronized (lock) { try { Thread.sleep(30 * 1000); } catch (InterruptedException e) { } } }
主线程sleep,先让另外一个线程拿到lock,并长期持有lock(sleep会持有锁,wait不会)。此时主线程会BLOCK住等待lock被释放,此时jstack的输出可以看到main线程状态是BLOCKED。这里要注意的是只有synchronized这种方式的锁(monitor锁)才会让线程出现BLOCKED状态,等待ReentrantLock则不会。
3) 让线程处于TIMED_WAITING状态
public static void timedWaiting() { final Object lock = new Object(); synchronized (lock) { try { lock.wait(30 * 1000); } catch (InterruptedException e) { } } }
1
4)让线程处于WAITING状态
public static void waiting() { final Object lock = new Object(); synchronized (lock) { try { lock.wait(); } catch (InterruptedException e) { } } }
无超时的等待,必须等待lock.notify()或lock.notifyAll()或接收到interrupt信号才能退出等待状态。
『捌』 java 线程wait和唤醒
suspend,使线程进入停滞状态,除非收到resume消息,否则该线程不会变回可执行状态。
wait():使一个线程处于等待状态,并且释放所持有的对象的lock;
sleep():使一个正在运行的线程处于睡眠状态,是一个静态方法,调用此方 法要捕捉InterruptedException异常;
notify():唤醒一个处于等待状态的线程,注意的是在调用此方法的时候, 并不能确切的唤醒某一个等待状态的线程,而是由JVM确定唤醒哪个线程,而且 不是按优先级;
notityAll():唤醒所有处入等待状态的线程,注意并不是给所有唤醒线程一 个对象的锁,而是让它们竞争。
『玖』 java 线程中wait和notify的问题
这个程序挺经典的.
我不知道你对wait这是不是很熟,我按我的说,有问题再沟通:
首先看
main函数,两句话,Procer对象和Consumer对象都引用了同一个p.
Procer类的run
前面有
synchronized(p)
说明该线程用到 synchronized 里的对象变量时,别的线程只能等待.
再看
if(p.bFull) {
try{p.wait();} catch (Exception e) {}
}
也就是说该线程用到了p对象,
而如果当运行到该线程时,
且p.bFull为真时
该线程进行等待,让其他线程运行
到这的思路如果没有问题,
那么我们假设
假设
p.bFull为假,
那么会再往下运行
也就是设置姓名,性别,
此时p.bFull仍然为假
之后设置 p.bFull 为真
p.notify()
当设置p.bFull为真时,表示下次如果仍然是该线程执行,将会wait.
而p.notify()是为了解以p为锁的线程,因为当前线程正在运行,所以当前线程肯定不需要解锁,那可能需要被解锁的,也就是Consumer对象的线程.
当前线程从开始运行到目前的位置,Consumer线程是一直在wait的,因为Consumer线程在while下面直接就synchronized (p)也就是这两个线程同时只能一个线程运行.
也就是说,要么这次运行Procer,要么运行Consumer
按我上面说的,Procer的运行逻辑应该已经清楚了,而Consumer的线程运行逻辑跟Procer一样,我就不多说了,
问题的关键在于
当Procer运行一次,之后Consumer运行一次,是比较好理解,交叉运行呗.
但如果Procer运行完,又运行了Procer线程,而没有让Consumer运行的时候,程序会怎么运行?(反之一样)
我下面来解释.
当Procer运行一次,又运行了Procer时,这时因为没有Consumer线程的介入
,p的bFull应该为真,
这时运行到
Procer线程的
if (p.bFull) {
try {
p.wait();
} catch (Exception e) {
}
时,因为p.bFull为真了,
所以运行下面的代码,
也就是让当前线程等待,而用来等待的锁就是p
这时,当前线程等待了,
也就要执行Consumer线程了,也就是相当于强制切换线程
运行一次Consumer线程后,Procer仍然在等待,如果这样,那就会仍然运行Consumer线程,根据逻辑,Consumer会像Procer一样,由于
if(!p.bFull) {
try{p.wait(); } catch (Exception e) {} }
而等待
这样两个线程都等待了
(如果你问,当!p.bFull如果成立,那p.bFull就不成立,那Procer不是该运行了吗?但是,我刚刚的假设是当Procer已经等待时,那么Procer就不会因为p.bFull的改变而继续运行了)
按上面所说,如果按这样的逻辑,最终会导致两个线程同时等待没有解锁,
为了解决这个问题,
就在程序的每个线程的
p.bFull = false;
后面,加上了
p.notify();
让以p为锁的线程解锁等待.
这样,就可以使程序的两个线程来回切换了.