方法名 |
用途 |
suspend |
线程暂停 |
resume |
恢复线程执行 |
一、基本应用
一个案例看懂 suspend() 与 resume() 的基本应用:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| public class ThreadSuspendAndResume { public static void main(String[] args) throws InterruptedException { MyThread myThread = new MyThread(); myThread.start(); Thread.sleep(500);
myThread.suspend(); System.out.println("A=" + System.currentTimeMillis() + " i=" + myThread.i); Thread.sleep(500); System.out.println("A=" + System.currentTimeMillis() + " i=" + myThread.i);
myThread.resume(); Thread.sleep(500);
myThread.suspend(); System.out.println("B=" + System.currentTimeMillis() + " i=" + myThread.i); Thread.sleep(500); System.out.println("B=" + System.currentTimeMillis() + " i=" + myThread.i);
myThread.stop(); System.out.println("END!"); } }
class MyThread extends Thread { public long i = 0;
@Override public void run() { while (true) { i++; } } }
|
执行结果:
1 2 3 4 5
| A=1613381037365 i=389072852 A=1613381037868 i=389072852 B=1613381038373 i=784162715 B=1613381038889 i=784162715 END!
|
从控制台上的时间和数值来看,线程的确是被暂停了,而且可以恢复成运行状态。
二、缺点——独占
这两个方法在使用不当的情况下,极易造成公共同步对象被独占,造成死锁(其他线程无法访问公共同步对象)的结果。
独占案例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| public class SuspendResumeDealLock {
public static void main(String[] args) { SuspendResumeDealLock that = new SuspendResumeDealLock();
Thread thread1 = new Thread() { @Override public void run() { System.out.println("线程a启动"); that.printString(); } };
thread1.setName("a"); thread1.start();
Thread thread2 = new Thread() { @Override public void run() { System.out.println("线程2启动"); that.printString(); System.out.println("线程2完成打印!!!!!"); } };
thread2.start(); }
synchronized public void printString() { System.out.println("begin"); if (Thread.currentThread().getName().equals("a")) { System.out.println("线程a进入永远暂停"); Thread.currentThread().suspend(); } System.out.println("end"); } }
|
打印结果:
1 2 3 4 5
| 线程a启动 线程2启动 begin 线程a进入永远暂停
|
a线程把 printString() 方法锁定了,造成 thread2 无法进入 printString()。
三、缺点——数据不完整
在使用suspend()方法和resume()方法时,容易出现线程暂停进而导致数不完整的情况。下面这个案例就是一个数据不完整的实例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
| public class SuspendResumeDealLock_3 { private String username = "1"; private String password = "11";
public void setValue(String u, String p) { this.username = u; if (Thread.currentThread().getName().equals("a")) { System.out.println("暂停线程a"); Thread.currentThread().suspend(); } this.password = p; }
public void printUsernamePassword() { System.out.println(username + " " + password); }
public static void main(String[] args) throws InterruptedException { new Run(); } }
class Run { public Run() throws InterruptedException { final SuspendResumeDealLock_3 myObject = new SuspendResumeDealLock_3();
Thread thread = new Thread() { @Override public void run() { myObject.setValue("a", "aa"); } };
thread.setName("a"); thread.start();
Thread.sleep(1000);
Thread thread1 = new Thread() { @Override public void run() { myObject.printUsernamePassword(); } }; thread1.start(); } }
|
运行结果:
线程的暂停和唤醒应当使用 wait()、notify()、notifyAll()方法。