本文目录一览:
- 1、谁能帮我解释一下java线程中的wait()方法的作用与执行原理非常感谢!
- 2、java中wait方法怎么条用
- 3、java线程wait方法
- 4、java同步中,为什么要wait,又notify谁?
- 5、java wait和sleep的区别
- 6、java wait的用法
谁能帮我解释一下java线程中的wait()方法的作用与执行原理非常感谢!
wait()方法是java.lang.Object类韦线程提供的用于实现线程间通信的同步控制方法。wait()方法使当前线程主动释放互斥锁,并进入该互斥锁的等待队列。(也就是说,它使当前线程暂停执行,等待其他线程执行notify()方法或者notifyall()方法后再继续执行本线程。)本方法用于释放一个项目的线程,唤醒另一个可能在等待的线程。有两种调用格式:
1.wait()等待通信线程唤醒后再继续执行本线程。
2.wait(long millis)等待通信线程唤醒或者最多等待millis毫秒后,再继续执行本线程。
我知道的就这么多了哈,希望对你能有一点帮助哦~~
java中wait方法怎么条用
wait方法用在 synchronized 方法或者 synchronized块中。一般在判断语句中,如果某条件被触发,让当前线程wait并释放对象的锁。此时可以让其他线程可以对用以对象调用synchronized方法。直到调用 notify或者notifyAll后 wait的线程才有可能执行。所以一般wait 和 notify是成对出现的。
java线程wait方法
wait和notify是用在多线程竞争同一锁资源的情况下使用的。
你这段代码实际是个单线程,这个线程自己把自己阻塞了,自然不可能自己把自己唤醒。
你的意图怎么实现呢?需要加入另外一个线程,下面是我仿照你的意图写的一段代码,供参考下
public class A
{
public A(){
final A a = this;
Thread th1 = new Thread(){
@Override
public void run(){
//一直循环,去尝试着唤醒a
try
{
this.sleep(10000);
} catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}//为检查是不是能真正实现唤醒a,等待10000毫秒,此时保证a已经处于等待状态中。
while(true){
/**
* 用notify唤醒的线程必须是持有当前锁对象的线程
*/
synchronized (a){
a.notify();
}
}
}
};
th1.setDaemon(true);//这句也是必须的,将th1设为守护线程,保证在唤醒a以后,所有活动的线程都为守护线程,jvm能及时推出
th1.start();//和a.run的顺序不可以换
this.run();
}
public static void main(String[] args)
{
new A();
}
public void run()
{
/**
* 这里可以换成这样,直接锁住this就行了
*/
synchronized (this)
{
try
{
this.wait();//阻塞当前的线程
} catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
System.out.println("1");//执行finally
}
}
}
}
java同步中,为什么要wait,又notify谁?
对象锁与同步块或者实例同步方法相关系,但如果线程进入静态同步方法,就必须获得类锁。用锁只能达到这样的目的:使得一个任务不会干涉另一个任务的资源,保证在任何时刻都只有一个任务可以访问某个资源。但两个任务要协同作战,互相通信,要一起工作去解决某个问题,必须使他们友好握手、共商国事。这种机制靠Object的方法wait()和notify()来安全地实现。在Thread对象上调用wait()方法将释放线程所有的锁定,这种说法是错误的。Thread类对象也是对象也有wait()方法,它释放的只是它自己作为线程对象的锁,这在线程池的概念级上理解。 似乎理解起来,wait()是自己停止,等待被唤醒;notify()也是自己停止,通知别人。那么感觉没什么大的区别,不急,先仔细分析他们的来历。wait()通常线程要执行下去需要等待某个条件发生变化,但改变这个条件已经超出了当前方法的控制能力。通常,这种条件由另一个任务来改变。既然执行不下去,傻等,又改变不了现实,那还不如交出执行权,令当前线程挂起,同步资源解锁,使别的线程可以访问并修改共享资源,自己进行排队队列,等候别人的通知。经过测试,好象是先入后出的顺序被唤醒的。释放了锁意味着另一个任务可以获得这个锁,这一点至关重要,因为这些其他的方法再入处理通常会引起wait()感兴趣的变化。wait()和notify()必须包括在synchronized代码块中,等待中的线程必须由notify()方法显式地唤醒,否则它会永远地等待下去。很多人初级接触多线程时,会习惯把wait()和notify()放在run()方法里,一定要谨记,这两个方法属于某个对象,应在对象所在的类方法中定义它,然后run中去调用它。 这里不得不提下,在Object的wait方法是重载的。有三个方法,了解一下除无参之外的另一个方法wait(毫秒数 n); 这里毫秒数是指,如果没有notify通知的情况下,当前被wait线程,经过n毫秒之后依然可以回到可运行状态。如果参数为零,则不考虑实际时间,在获得通知前该线程将一直等待。wait(0, 0) 与 wait(0) 相同。 notify()唤醒正在队列中等待资源的优先级最高的线程。但它自己不马上退出资源,继续执行,等全部执行完了,退出,释放锁,这样才让wait()的线程进入。所以说在对象(当前线程具有其锁定)调用notify()方法一定释放锁定是只是一厢情愿的。至于与notifyAll()区别,后者更加安全。使用notify(),在众多等待同一个锁的任务中只有一个会被唤醒,因此如果你希望使用notify(),就必须保证被唤醒的是恰当的任务。notify()也就是this.notify(),唤醒所有争抢自己的线程,与别的对象产生的wait()没有关系。 synchronized (a) {
System.out.println("notify");
a.notifyAll(); //假如这里是wait(),下句代码就暂时不会执行!
System.out.println("continue"); //notifyAll()以后,这句代码还是要执行的
} 我曾经自己写过如下非常幼稚的代码,写在public void run()里边,目的是在zoneRectangleSize 1的情况下,使自己的线程处于阻塞状态,虽然不会出错,但这个wait调用的是线程类对象本身的wait(),毕竟它也是来自Object,所以肯定达不到预期的效果: synchronized (mainApp) {
} Thread的静态方法sleep()是不释放锁的,也不用操作锁,所以可以在非同步控制方法和run方法内部调用。也就是说当前线程即使进入sleep状态也抱着这把锁睡觉,保持高度的监控状态,即使其它线程在外边踢门叫嚷骂娘,他是心安理得,坚决不释放。如果一直昏睡下去,拥有同一对象资源的线程们都会玩完的。
java wait和sleep的区别
一
sleep 是线程类(Thread)的方法,导致此线程暂停执行指定时间,给执行机会给其他线程,但是监控状态依然保持,到时后会自动恢复,调用sleep 不会释放对象锁。由于没有释放对象锁,所以不能调用里面的同步方法。
sleep()使当前线程进入停滞状态(阻塞当前线程),让出CUP的使用、目的是不让当前线程独自霸占该进程所获的CPU资源,以留一定时间给其他线程执行的机会;
sleep()是Thread类的Static(静态)的方法;因此他不能改变对象的机锁,所以当在一个Synchronized块中调用Sleep()方法是,线程虽然休眠了,但是对象的机锁并木有被释放,其他线程无法访问这个对象(即使睡着也持有对象锁)。
在sleep()休眠时间期满后,该线程不一定会立即执行,这是因为其它线程可能正在运行而且没有被调度为放弃执行,除非此线程具有更高的优先级。
wait()方法是Object类里的方法;当一个线程执行到wait()方法时,它就进入到一个和该对象相关的等待池中,同时失去(释放)了对象的机锁(暂时失去机锁,wait(long timeout)超时时间到后还需要返还对象锁);可以调用里面的同步方法,其他线程可以访问;
wait()使用notify或者notifyAlll或者指定睡眠时间来唤醒当前等待池中的线程。
wiat()必须放在synchronized block中,否则会在program runtime时扔出”java.lang.IllegalMonitorStateException“异常。
二
sleep必须捕获异常,而wait,notify和notifyAll不需要捕获异常
sleep方法属于Thread类中方法,表示让一个线程进入睡眠状态,等待一定的时间之后,自动醒来进入到可运行状态,不会马上进入运行状态,因为线程调度机制恢复线程的运行也需要时间,一个线程对象调用了sleep方法之后,并不会释放他所持有的所有对象锁,所以也就不会影响其他进程对象的运行。但在sleep的过程中过程中有可能被其他对象调用它的interrupt(),产生InterruptedException异常,如果你的程序不捕获这个异常,线程就会异常终止,进入TERMINATED状态,如果你的程序捕获了这个异常,那么程序就会继续执行catch语句块(可能还有finally语句块)以及以后的代码。
注意sleep()方法是一个静态方法,也就是说他只对当前对象有效,通过t.sleep()让t对象进入sleep,这样的做法是错误的,它只会是使当前线程被sleep 而不是t线程
wait属于Object的成员方法,一旦一个对象调用了wait方法,必须要采用notify()和notifyAll()方法唤醒该进程;如果线程拥有某个或某些对象的同步锁,那么在调用了wait()后,这个线程就会释放它持有的所有同步资源,而不限于这个被调用了wait()方法的对象。wait()方法也同样会在wait的过程中有可能被其他对象调用interrupt()方法而产生
三
这两者的施加者是有本质区别的.
sleep()是让某个线程暂停运行一段时间,其控制范围是由当前线程决定,也就是说,在线程里面决定.好比如说,我要做的事情是 "点火-烧水-煮面",而当我点完火之后我不立即烧水,我要休息一段时间再烧.对于运行的主动权是由我的流程来控制.
支持一下吆 收藏一下: 很好
而wait(),首先,这是由某个确定的对象来调用的,将这个对象理解成一个传话的人,当这个人在某个线程里面说"暂停!",也是 thisOBJ.wait(),这里的暂停是阻塞,还是"点火-烧水-煮饭",thisOBJ就好比一个监督我的人站在我旁边,本来该线 程应该执行1后执行2,再执行3,而在2处被那个对象喊暂停,那么我就会一直等在这里而不执行3,但正个流程并没有结束,我一直想去煮饭,但还没被允许, 直到那个对象在某个地方说"通知暂停的线程启动!",也就是thisOBJ.notify()的时候,那么我就可以煮饭了,这个被暂停的线程就会从暂停处 继续执行.
其实两者都可以让线程暂停一段时间,但是本质的区别是一个线程的运行状态控制,一个是线程之间的通讯的问题
在java.lang.Thread类中,提供了sleep(),
而java.lang.Object类中提供了wait(), notify()和notifyAll()方法来操作线程
sleep()可以将一个线程睡眠,参数可以指定一个时间。
而wait()可以将一个线程挂起,直到超时或者该线程被唤醒。
wait有两种形式wait()和wait(milliseconds).
sleep和wait的区别有:
1,这两个方法来自不同的类分别是Thread和Object
2,最主要是sleep方法没有释放锁,而wait方法释放了锁,使得其他线程可以使用同步控制块或者方法。
3,wait,notify和notifyAll只能在同步控制方法或者同步控制块里面使用,而sleep可以在
任何地方使用
synchronized(x){
x.notify()
//或者wait()
}
4,sleep必须捕获异常,而wait,notify和notifyAll不需要捕获异常
java wait的用法
wait是Object的方法,也就是说可以对任意一个对象调用wait方法,调用wait方法将会将调用者的线程挂起,直到其他线程调用同一个对象的notify方法才会重新激活调用者,例如:
//Thread 1
try{
obj.wait();//suspend thread until obj.notify() is called
}
catch(InterrputedException e) {
}