多线程之暂停与恢复suspend和resume

一:简介

              暂停线程意味着此线程还可以恢复运行。通过suspend()函数,可使线程进入停滞状态。
             通过suspend()使线程进入停滞状态后,除非收到resume()消息,否则该线程不会变回
             可执行状态。注意如果在线程没有挂起时(就是没有调用suspend()方法前)去调用
             Resume()方法会出现异常,所以使用这样的方法进行线程线程同步已经不推荐使用了。

二:简单案例演示

  1. 创建MyThread类
        
    package com.kgf.test;
    
    public class MyThread extends Thread {
    
    	private long i = 0;
    	
    	public long getI() {
    		return i;
    	}
    
    	public void setI(long i) {
    		this.i = i;
    	}
    	@Override
    	public void run() {
    		while(true) {
    			i++;
    		}
    	}
    }
    

     

  2. 创建测试类
       
    package com.kgf.test;
    
    public class Run {
    
    	public static void main(String[] args) throws InterruptedException {
    		try {
    			MyThread thread = new MyThread();
    			thread.start();
    			Thread.sleep(2000);
    			
    			//A段
    			thread.suspend();//暂停
    			System.out.println("A1="+System.currentTimeMillis()+" i="+thread.getI());
    			Thread.sleep(2000);
    			System.out.println("A2="+System.currentTimeMillis()+" i="+thread.getI());
    			
    			//B段
    			thread.resume();//释放
    			Thread.sleep(2000);
    			
    			//C段
    			thread.suspend();//暂停
    			System.out.println("C1="+System.currentTimeMillis()+" i="+thread.getI());
    			Thread.sleep(2000);
    			System.out.println("C2="+System.currentTimeMillis()+" i="+thread.getI());
    		} catch (Exception e) {
    			System.out.println("main catch");
    			e.printStackTrace();
    		}
    		System.out.println("==========END================");
    	}
    }
    

     

  3.  效果
       多线程之暂停与恢复suspend和resume_第1张图片
       从控制台的打印时间上来看,线程的确被暂停了,而且还可以恢复为运行的状态。            

三:suspend与resume方法的缺点“独占”

  1.  简介
           在使用suspend和resume方法时,如果使用不当,极易造成公共的同步对象
     的独占,使其它线程无法访问公共同步对象。
  2. 简单代码示例1
            ⑴创建SynchronizedObject类
                        多线程之暂停与恢复suspend和resume_第2张图片
            ⑵测试类 
                       
    package com.kgf.test;
    
    public class Run {
    
    	public static void main(String[] args) throws InterruptedException {
    		try {
    			final SynchronizedObject object = new SynchronizedObject();
    			Thread thread1 = new Thread() {//创建线程1
    				@Override
    				public void run() {
    					object.printString();//调用SynchronizedObject中的方法
    				}
    			};
    			thread1.setName("a");
    			thread1.start();//启动线程1
    			Thread.sleep(1000);//主线程睡眠1秒钟
    			
    			Thread thread2 = new Thread() {//创建线程2
    				@Override
    				public void run() {
    					System.out.println("thread2启动了。。。。");
    					object.printString();//调用SynchronizedObject中的方法
    					System.out.println("thread2进来了吗?。。。。");
    				}
    			};
    			thread2.start();//启动线程2
    		} catch (Exception e) {
    			System.out.println("main catch");
    			e.printStackTrace();
    		}
    		System.out.println("==========END================");
    	}
    }
    

            ⑶效果:
                   多线程之暂停与恢复suspend和resume_第3张图片
            ⑷结果分析:
                        通过上面的代码可知,我们将线程thread1在printString方法中使用suspend方法
                暂停后没有释放,最后导致这个方法的锁一直被这个线程所占用,thread2完全无法调用
  3.  简单代码示例2
             ⑴创建MyThread类
                     多线程之暂停与恢复suspend和resume_第4张图片
             ⑵测试类
                     多线程之暂停与恢复suspend和resume_第5张图片
             ⑶效果
                      多线程之暂停与恢复suspend和resume_第6张图片
             ⑷结果分析:
                        我们可以发现当我们把thread线程暂停后,主线程中的"main end"都没有打印。那么这个
                 是什么原因导致的呢?我们查看一下printIn()源代码如下:
                  多线程之暂停与恢复suspend和resume_第7张图片
                  这个是PrintStream对象中的println方法,是个同步锁的方法,这时候应该就明白了。出现
                  这样情况的原因是当thread线程程序运行到printIn()方法内部停止时,同步锁未被释放,这
                  导致当前PrintStream对象的printIn()方法一直呈“暂停”状态。而且这个PrintStream是唯一的,
                  thread线程里面的没有释放,下面main方法中也无法使用printIn()方法打印。我们可以看一下
                  System类中的PrintStream对象的定义:
                  多线程之暂停与恢复suspend和resume_第8张图片     

四:suspend与resume方法的缺点“不同步”

  1. 简介
           在使用suspend与resume方法时也容易出现因为线程的暂停而导致数据不同步的情况。
  2. 代码实例
           ⑴创建MyObject类
                      
    package com.kgf.test;
    
    public class MyObject {
    
    	private String username = "111";
    	
    	private String password = "222";
    	
    	public void setValue(String u,String p) {
    		this.username = u;
    		if(Thread.currentThread().getName().equals("a")) {
    			System.out.println("停止a线程!");
    			Thread.currentThread().suspend();//暂停a线程
    		}
    		this.password = p;
    	}
    	
    	public void printInfo() {
    		System.out.println(username+" "+password);
    	}
    	
    }
    

           ⑵测试类
                   
    package com.kgf.test;
    
    public class Run {
    
    	public static void main(String[] args) throws InterruptedException {
    		try {
    			final MyObject object = new MyObject();
    			Thread thread1 = new Thread() {//创建线程1
    				@Override
    				public void run() {
    					object.setValue("a","aa");
    				}
    			};
    			thread1.setName("a");
    			thread1.start();//启动线程1
    			Thread.sleep(500);
    			
    			Thread thread2 = new Thread() {//创建线程2
    				@Override
    				public void run() {
    					object.printInfo();
    				}
    			};
    			thread2.start();//启动线程2
    		} catch (Exception e) {
    			System.out.println("main catch");
    			e.printStackTrace();
    		}
    		System.out.println("==========END================");
    	}
    }
    

           ⑶  效果
                    多线程之暂停与恢复suspend和resume_第9张图片
           ⑷ 结果分析:
                     从上面的代码可知a线程执行代码到一半的时候,将对象MyObject中的变量值修改了一个,
                然后将线程暂停了,后面线程再打印的时候发现数据已经出现了不同步的问题。 

你可能感兴趣的:(多线程)