java多线程suspend、resume暂停与恢复线程
2018-02-28 11:10
393 查看
今天复习java多线程时,发现一个自己比较陌生的知识点,就是多线程的suspend(暂停线程)和resume(释放线程),虽然这两个方法已经被弃用,但了解一下,也会对多线程更加有深刻的理解吧。
首先我直接上代码,来看一下,它是如何暂停线程和释放线程的。class MyThread extends Thread{
private long i=0;
public long getI() {
return i;
}
public void setI(long i) {
this.i = i;
}
public void run(){
while(true){
i++;
}
}
}
public class Run{
public static void main(String[] args) {
try {
MyThread thread=new MyThread();
thread.start();//启动线程
Thread.sleep(5000);//主线程挂起
thread.suspend();//thread线程暂停
System.out.println("a="+System.currentTimeMillis()+" i="+thread.getI());//获取系统时间下的i值
Thread.sleep(5000);//主线程挂起
System.out.println("a="+System.currentTimeMillis()+" i="+thread.getI());//获取系统时间下的i值
//很显然以上两者的i值是相同的
thread.resume();//恢复线程
Thread.sleep(5000);
thread.suspend();
System.out.println("B="+System.currentTimeMillis()+" i="+thread.getI());
Thread.sleep(5000);
System.out.println("B="+System.currentTimeMillis()+" i="+thread.getI());
那么为什么这两个方法为什么会被弃用呢?我想估计也会有一下两种情况吧。
1、独占同步对象,导致其他线程无法访问同步对象。
class SynchronizedObject{
synchronized public void printString(){
System.out.println("begin");
if(Thread.currentThread().getName().equals("a")){
System.out.println("a 线程永远suspend了");
Thread.currentThread().suspend();
}
System.out.println("end");
}
}
publicclassRun{
publicstaticvoid main(String[] args) {
try {
final SynchronizedObject object=new SynchronizedObject();
Threadt1=new Thread(){
publicvoid run(){
object.printString();
}
};
t1.setName("a");
t1.start();
Thread.sleep(1000);
Thread t2=new Thread(){
public void run(){
System.out.println("t2启动了,但进入不了printString(),只打印了1个begin");
System.out.println("因为printString方法被a线程锁定并且永远suspend暂停了");
object.printString();
}
};
}catch(InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("end!");
}
}
在线程t1拿到锁之后,进入被synchronizd修饰的方法时,此时如果调用suspend方法,就会造成t1线程,没有释放锁,而进入暂停的状态,t1就进入一直暂停的状态。t2线程可以启动,但是他却拿不到该锁,因此会发生阻塞。
另外还有一中情况需要特别注意。class MyThread extends Thread{
private int i=0;
public void run(){
while(true){
i++;
System.out.println(i);
}
}
}
public class Run{
public static void main(String[] args) {
try {
MyThread thread=new MyThread();
thread.start();
Thread.sleep(1000);
thread.suspend();
System.out.println("main end");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("end!");
}
}运行结果没有main end,为什么呢?
这里需要看一下println的源码,println方
4000
法是线程安全的,也就是,在打印前需要难道锁对象,也就是out中的常量public final static PrintStream out = null;此处的out对象就是方法println中使用的锁对象。因为“thread”线程在拿到锁之后,又被suspend,此时thread线程并没有释放锁对象,而当进入主线程的System.out.println("main end");这句时,主线程并拿不到锁对象,而处于阻塞状态,因此才会没有main end的打印。
![](https://img-blog.csdn.net/2018022810483689?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcXFfMzY3OTU0NzQ=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)
2、suspend和resume会导致数据不同步的情况。public class Run{
public static void main(String[] args) {
try {
final SynchronizedObject object=new SynchronizedObject();
Thread t1=new Thread(){
public void run(){
object.setValue("a","aa");
}
};
t1.setName("a");
t1.start();
Thread.sleep(1000);
Thread t2=new Thread(){
public void run(){
object.print();
}
};
t2.start();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("end!");
}
}
class SynchronizedObject{
private String userName="l";
private String passWord="ll";
public void setValue(String u,String p){
this.userName=u;
if(Thread.currentThread().getName().equals("a"));
{
System.out.println("停止线程");
Thread.currentThread().suspend();
}
this.passWord=p;
}
public void print(){
System.out.println(userName+" "+passWord);
}
}
![](https://img-blog.csdn.net/20180228110844887?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcXFfMzY3OTU0NzQ=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)
从以上可以看出,使用suspend会出现数据不同步的情况。
首先我直接上代码,来看一下,它是如何暂停线程和释放线程的。class MyThread extends Thread{
private long i=0;
public long getI() {
return i;
}
public void setI(long i) {
this.i = i;
}
public void run(){
while(true){
i++;
}
}
}
public class Run{
public static void main(String[] args) {
try {
MyThread thread=new MyThread();
thread.start();//启动线程
Thread.sleep(5000);//主线程挂起
thread.suspend();//thread线程暂停
System.out.println("a="+System.currentTimeMillis()+" i="+thread.getI());//获取系统时间下的i值
Thread.sleep(5000);//主线程挂起
System.out.println("a="+System.currentTimeMillis()+" i="+thread.getI());//获取系统时间下的i值
//很显然以上两者的i值是相同的
thread.resume();//恢复线程
Thread.sleep(5000);
thread.suspend();
System.out.println("B="+System.currentTimeMillis()+" i="+thread.getI());
Thread.sleep(5000);
System.out.println("B="+System.currentTimeMillis()+" i="+thread.getI());
/以上两者的i值是相同的,但不同与前面的i值 } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("end!"); } }通过以上代码,我们就可以发现suspend和resume方法的基本功能。
那么为什么这两个方法为什么会被弃用呢?我想估计也会有一下两种情况吧。
1、独占同步对象,导致其他线程无法访问同步对象。
class SynchronizedObject{
synchronized public void printString(){
System.out.println("begin");
if(Thread.currentThread().getName().equals("a")){
System.out.println("a 线程永远suspend了");
Thread.currentThread().suspend();
}
System.out.println("end");
}
}
publicclassRun{
publicstaticvoid main(String[] args) {
try {
final SynchronizedObject object=new SynchronizedObject();
Threadt1=new Thread(){
publicvoid run(){
object.printString();
}
};
t1.setName("a");
t1.start();
Thread.sleep(1000);
Thread t2=new Thread(){
public void run(){
System.out.println("t2启动了,但进入不了printString(),只打印了1个begin");
System.out.println("因为printString方法被a线程锁定并且永远suspend暂停了");
object.printString();
}
};
}catch(InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("end!");
}
}
在线程t1拿到锁之后,进入被synchronizd修饰的方法时,此时如果调用suspend方法,就会造成t1线程,没有释放锁,而进入暂停的状态,t1就进入一直暂停的状态。t2线程可以启动,但是他却拿不到该锁,因此会发生阻塞。
另外还有一中情况需要特别注意。class MyThread extends Thread{
private int i=0;
public void run(){
while(true){
i++;
System.out.println(i);
}
}
}
public class Run{
public static void main(String[] args) {
try {
MyThread thread=new MyThread();
thread.start();
Thread.sleep(1000);
thread.suspend();
System.out.println("main end");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("end!");
}
}运行结果没有main end,为什么呢?
这里需要看一下println的源码,println方
4000
法是线程安全的,也就是,在打印前需要难道锁对象,也就是out中的常量public final static PrintStream out = null;此处的out对象就是方法println中使用的锁对象。因为“thread”线程在拿到锁之后,又被suspend,此时thread线程并没有释放锁对象,而当进入主线程的System.out.println("main end");这句时,主线程并拿不到锁对象,而处于阻塞状态,因此才会没有main end的打印。
2、suspend和resume会导致数据不同步的情况。public class Run{
public static void main(String[] args) {
try {
final SynchronizedObject object=new SynchronizedObject();
Thread t1=new Thread(){
public void run(){
object.setValue("a","aa");
}
};
t1.setName("a");
t1.start();
Thread.sleep(1000);
Thread t2=new Thread(){
public void run(){
object.print();
}
};
t2.start();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("end!");
}
}
class SynchronizedObject{
private String userName="l";
private String passWord="ll";
public void setValue(String u,String p){
this.userName=u;
if(Thread.currentThread().getName().equals("a"));
{
System.out.println("停止线程");
Thread.currentThread().suspend();
}
this.passWord=p;
}
public void print(){
System.out.println(userName+" "+passWord);
}
}
从以上可以看出,使用suspend会出现数据不同步的情况。
相关文章推荐
- java线程的暂停和恢复 suspend 和resume
- java线程暂停与恢复suspend和resume
- java线程停止、暂停和恢复等状态的控制
- JAVA多线程之线程的挂起与恢复(suspend方法与resume方法)
- Android中的java层的线程暂停和恢复实现
- 2010-05-23 14:48 Java(6)线程暂停、恢复
- Android中java线程的暂停与恢复
- Java多线程之线程的挂起与恢复(Suspend/Resume)
- Java线程优先级和线程暂停恢复的问题
- java线程(暂停、恢复、结束)前引
- Android中的java层的线程暂停和恢复实现
- 暂停线程suspend()和恢复线程resume()
- java线程停止、暂停和恢复等状态的控制
- java多线程基础(6)-调度方式之暂停当前线程方式5-等待(wait)
- Java线程中sleep()、wait()和notify()和notifyAll()、suspend和resume()、yield()、join()、interrupt()的用法和区别
- Java线程同步阻塞, sleep(), suspend(), resume(), yield(), wait(), notify()
- 利用ManualResetEvent来来控制异步调用的打印的线程的暂停和恢复(转)
- C++多线程编程经验——线程暂停、恢复
- C# winform 多线程异步操作线程启动暂停与恢复
- linux中线程的挂起与恢复(进程暂停)