多线程学习笔记(二)线程的挂起跟恢复
什么是挂起线程?
线程的挂起操作实质上就是使线程进入“非可执行”状态下,在这个状态下CPU不会分给线程时间片,进入这个状态可以用来暂停一个线程的运行。
在线程挂起后,可以通过重新唤醒线程来使之恢复运行
为什么要挂起线程?
cpu分配的时间片非常短、同时也非常珍贵。避免资源的浪费。
如何挂起线程?
被废弃的方法
thread.suspend() 该方法不会释放线程所占用的资源。如果使用该方法将某个线程挂起,则可能会使其他等待资源的线程死锁
thread.resume() 方法本身并无问题,但是不能独立于suspend()方法存在
可以使用的方法
wait() 暂停执行、放弃已经获得的锁、进入等待状态
notify() 随机唤醒一个在等待锁的线程
notifyAll() 唤醒所有在等待锁的线程,自行抢占cpu资源
什么时候适合使用挂起线程?
我等的船还不来(等待某些未就绪的资源),我等的人还不明白。直到notify方法被调用
实例一:使用suspend 和 resume 挂起和恢复线程
public class SuspendDome implements Runnable{ @Override public void run() { System.out.println(Thread.currentThread().getName()+"开始运行,准备挂起"); Thread.currentThread().suspend();//挂起线程 System.out.println(Thread.currentThread().getName()+"结束"); } public static void main(String[] args) throws InterruptedException { Thread thread = new Thread(new SuspendDome()); thread.start(); Thread.sleep(3000L); thread.resume();//唤醒线程 } }
实例二:使用使用suspend 和 resume 造成死锁
public class DeadDome implements Runnable { public static Object object = new Object(); //创建一个资源 @Override public void run() { synchronized (object){ //锁住该资源 System.out.println(Thread.currentThread().getName()+"持有资源,准备挂起"); Thread.currentThread().suspend(); } System.out.println(Thread.currentThread().getName()+"释放资源"); } public static void main(String[] args) throws InterruptedException { Thread thread = new Thread(new DeadDome(),"对比线程"); thread.start(); Thread.sleep(1000L); thread.resume(); Thread thread1 = new Thread(new DeadDome(),"死锁线程"); thread1.start(); thread1.resume(); } }
实例三:使用wait 和 notify 挂起和唤醒进程
public class WaitDome implements Runnable { public static Object waitObject = new Object(); @Override public void run() { synchronized (waitObject) { //锁住该资源 System.out.println(Thread.currentThread().getName() + "持有资源,准备挂起"); try { waitObject.wait();//挂起之前 必须获得这个这锁 } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println(Thread.currentThread().getName() + "释放资源"); } public static void main(String[] args) throws InterruptedException { Thread thread = new Thread(new WaitDome(), "对比线程"); thread.start(); Thread.sleep(1000L); synchronized (waitObject){ waitObject.notify(); } } }