Ⅰ 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培训学校告诉你关于线程安全问题分析
在学习java编程开发语言的过程中,我们掌握了线程与线程池等相关技术知识。今天,北大青鸟云南计算机学院http://www.kmbdqn.cn/就关于线程安全问题给大家做一个简单的喊枝答说明和介绍,一起来了解一下吧。
线程安全就是多线程访问时,采用了加锁机制,当一个线程访问该类的某个数据时,进行保护,其他线程不能进行访问直到该线程读取完,其他线程才可使用。不会出现数据不一致或者数据污染。
线程不安全就是不提供数据访问保护,有可能出现多个线程先后更改数据造成所得到的数据是脏数据搭罩。
什么时候考虑到线程安全:
一个对象是否需要线程安全,取决于该对象是否被多线程访问。这指的是程序中访问对象的方式,而不是对象要实现的功能。要使得对象是线程安全的,要采用同步机制来协同对对象可变状态的访问。Java常用的同步机制是Synchronized,还包括volatile类型的变量,显示锁以及原子变量。在多个线程中,当它们同时访问同个类时,每次执行的结果和单线程结果一致,且变量值跟预期一致,这个类则是线程安全的。
锁的特性
锁机制的两种特性:
互斥性:即同一时间只允许一个线程持有某个对象的锁,通过这种特性来实现多线程中的协调机制,这样在同一时间只有一个线程对需同步的代码块(复合操作)进行访问。互斥性我们也往往称为操作的原子性。
可见性:必须确保在锁被释放之前,对共享变量所做的修改,对于随后获得该锁的另一个线程是可见的,否则另一个线程可能是在本地缓存的某个副本上继续操作从而引起不一致。
挂起、休眠、阻塞和非阻塞
挂起:当线程被挂起时,其会失去CPU的使用时间,直到被其他线程(用户线程或调试线程)唤醒。
休眠:同样是会失去CPU的使用时间,但是在过了指定的休眠时间之后,它会自动激活,无需唤醒(整个唤醒表面看是自动的,但实际上也得有守护线程去唤醒,只是不需编程者手动干预)。
阻塞:在线程执行时,所需要的资源不能得到,则线程被挂起,直到满足可操作的条件。
非阻塞:在线程执行时,郑慧所需要的资源不能得到,则线程不是被挂起等待,而是继续执行其余事情,等待条件满足了后,收到了通知(同样是守护线程去做)再执行。
Ⅲ JAVA里面线程的阻塞状态和挂起状态'的区别
阻塞就是路给堵死了,随便等多久都不痛。。。
挂起就是等一段时间就会通!
Ⅳ java中如何启动一个新的线程
java开启新线程的三种方法:
方法1:继承Thread类
1):定义一个继承自Java.lang.Thread类的类A.
2):覆盖A类Thread类中的run方法。
3):我们编写需要在run方法中执行的操作:run方法中的代码,线程执行体。
4):在main方法(线程)中,创建一个线程对象并启动线程。
(1)创建线程类对象:
A类 a = new A类();
(2)调用线程对象的start方法:
a.start();//启动一个线程
注意:不要调用run方法。如果run方法被称为对象调用方法,则仍然只有一个线程,并且没有启动新线程。
创建启动线程实例:
(4)java挂起线程扩展阅读:
启动新线程的两种方式对比
继承方式:
1):从设计上分析,Java中类是单继承的,如果继承了Thread了,该类就不能再有其他的直接父类了.
2):从操作上分析,继承方式更简单,获取线程名字也简单.(操作上,更简单)
3):从多线程共享同一个资源上分析,继承方式不能做到.
实现方式:
1):从设计上分析,Java中类可以多实现接口,此时该类还可以继承其他类,并且还可以实现其他接口,设计更为合理.
2):从操作上分析,实现方式稍微复杂点,获取线程名字也比较复杂,得使用Thread.currentThread()来获取当前线程的引用.
3):从多线程共享同一个资源上分析,实现方式可以做到(是否共享同一个资源).
补充:实现方式获取线程名字:
String name = Thread.currentThread().getName();
Ⅳ javathreat.stop报错
javathreat.stop报错
以下核陆包含javathreadstop报错的结果,仍然搜索javathreatstop报错
java线程stop方法不能用 - java线程无法正常停止总结 - masaki叔还是这么可 ...
1. 死锁。这个很容易借助jdk提供的工具定位到对应的代码位置,使用jps 然后jstack id。就能够看到BEBLOCK状态,并有对应的代码堆栈。
2. 线程挂起。并不是死锁现象,而是线历氏旦程挂起,线程状态时RUNNING状态,这中就不好定位了,因为线程状态一直时RUNNING状态,很容易就当成服务的正常状态了。针对这种问题
3. 自己开辟的线程不是肢扰后台线程,该线程一直不会停止
Ⅵ java关于等待线程结束的问题!
简单地可以使用 Thread.join() 方法来等待线程结束,例如这样修改一下:
Threadt=局悔newThread(){
//同团腊散原来的run()
};
t.start();
//调用这个方法,会挂起当前线程直至线程t结束
t.join();
join()方法的文档是这么写的: Waits for this thread to die.
也可以用wait/notify或mutex等机制来对两个线程进行同步,稍微复杂一点,例如使用 wait/notify:
newThread(){
publicvoidrun(){
//同原来的代码,加上以下代码用于同步
synchronized(results){
results.notifyAll();
}
}
}.start();
//通过以下代码挂起当前线程,等待其他线程通知
synchronized(results){
results.wait();
}
以供参考。
同 i178269245 所说,等待线程结束势必要挂起当前线程,也就没必要用线程了,也许需要重新考虑一下这种实现方式塌氏。
Ⅶ java 中线程睡眠和挂起区别
wait是进入队桐毕列等待获取锁,notify是橘凳在已经占有锁的时候释放锁,并通知wait队列里的某一个线程起来圆轮旅去获取锁。
Ⅷ 在Java中什么叫一个线程被挂起
就是说你自己定义了一个线程事件 你需要它运行 当它运行一段时间后为了实现汪激某项功能你需要它停止 或者休眠 比如stop() sleep()方蚂租法 我们叫线闷陵兆程挂起
Ⅸ java线程挂起是什么意思
资源仍被占用,不被是释放。