java多线程suspend、resume暂停与恢复线程

       今天复习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());
                       /以上两者的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方法是线程安全的,也就是,在打印前需要难道锁对象,也就是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会出现数据不同步的情况。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值