线程暂停与恢复用suspend()和resume()函数进行操作,下面为使用的实例:
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++;
}
}
public class Main {
public static void main(String[] args) {
Mythread mythread = new Mythread();
try {
mythread.start();
Thread.sleep(5000);
mythread.suspend();
System.out.println("A= " + System.currentTimeMillis() +
" i=" + mythread.getI());
Thread.sleep(5000);
System.out.println("A= " + System.currentTimeMillis() +
" i=" + mythread.getI());
mythread.resume();
Thread.sleep(5000);
mythread.suspend();
System.out.println("B= " + System.currentTimeMillis() +
" i=" + mythread.getI());
Thread.sleep(5000);
System.out.println("B= " + System.currentTimeMillis() +
" i=" + mythread.getI());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
运行的结果如下
A= 1573916447232 i=3989910604
A= 1573916452233 i=3989910604
B= 1573916457233 i=8003591732
B= 1573916462234 i=8003591732
诚然,suspend()和resume()方法的确实现了线程的暂停和恢复。但是也有它的缺点:
1. 独占
在使用suspend和resume方法时,如果使用不当,容易造成公共的同步对象的独占。如在一个有同步锁的方法中让当前线程suspend了,则这个线程就可能永久的suspend了。其他线程无法进入这个同步函数。更要注意某种比较隐晦的场景:
public class Mythread extends Thread{
private long i = 0;
@Override
public void run(){
while (true)
i++;
}
}
public class Main {
public static void main(String[] args) {
Mythread mythread = new Mythread();
try {
mythread.start();
Thread.sleep(5000);
mythread.suspend();
System.out.println("main end");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
如上线程,可以正确执行并打印出
main end
但是如果把Mythread换成
public class Mythread extends Thread{
private long i = 0;
@Override
public void run(){
while (true) {
i++;
System.out.println(i);
}
}
}
线程会一直打印直到suspend,但是不会打印出main end
因为在println方法中,有同步锁。当程序运行到println()方法内部停止时,同步锁没有释放,就会导致当前print方法一直处于暂停的状态,并且锁没有释放,main代码中的System.out.println("main end");不能被打印
2. 不同步
public class MyObject {
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("suspend a thread!");
Thread.currentThread().suspend();
}
this.password = p;
}
public void printUP() {
System.out.println(username + " " + password);
}
}
public class Main {
public static void main(String[] args) {
try {
MyObject myObject = new MyObject();
Thread thread = new Thread(){
public void run() {
myObject.setValue("a", "aa");
}
};
thread.setName("a");
thread.start();
Thread.sleep(5000);
Thread thread2 = new Thread(){
public void run() {
myObject.printUP();
}
};
thread2.start();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
运行结果:
thread被suspend了,在thread2执行打印时,打印了password的初始值,造成数据不同步出现不同步的现象。
在线程方法外加个resume,可以让线程恢复,主要要先sleep,保证setValue函数已经调用完suspend
public class Main {
public static void main(String[] args) {
try {
MyObject myObject = new MyObject();
Thread thread = new Thread(){
public void run() {
myObject.setValue("a", "aa");
}
};
thread.setName("a");
thread.start();
// 在调用resume前sleep,保证thread线程已经调用玩suspend,接下来再调用resume
Thread.sleep(1000);
thread.resume();
//Thread.sleep(1000);
Thread thread2 = new Thread(){
public void run() {
myObject.printUP();
}
};
thread2.start();
} catch (Exception e) {
e.printStackTrace();
}
}
}