暂停线程(菜鸟玩线程)
程序员文章站
2022-05-31 14:17:26
...
暂停线程
暂停线程,即线程还可以恢复运行。
Java多线程中,可以使用suspend()方法停止线程,使用resume()方法恢复线程的执行。
suspend与resume方法的使用
直接上代码:
自定义线程类
package com.thread9;
public class MyThread extends Thread {
private long i;
public long getI() {
return i;
}
public void setI(long i) {
this.i = i;
}
@Override
public void run() {
while (true) {
i++;
}
}
}
启动类
package com.thread9;
public class Run {
public static void main(String[] args) {
try {
MyThread myThread = new MyThread();
myThread.start();
Thread.sleep(5000);
//A段
myThread.suspend();
System.out.println("A = " + System.currentTimeMillis() + " , i =" + myThread.getI());
Thread.sleep(5000);
System.out.println("A = " + System.currentTimeMillis() + " , i =" + myThread.getI());
//B段
myThread.resume();
Thread.sleep(5000);
System.out.println("醒了");
//C段
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 = 1541211738334 , i =3401982429
A = 1541211743334 , i =3401982429
醒了
B = 1541211748334 , i =6686269724
B = 1541211753334 , i =6686269724
结论
从输出结果中看,主要看i变量,线程的确贝暂停了,而且还可以恢复成运行状态。
但是运行起来,线程结束不了????
suspend与resume方法的缺点——独占
如果使用不当,极容易早晨公共的同步对象的独占,使得其他线程无法访问公共同步对象。
代码实例如下:
自定义线程类
package com.thread10;
public class MyThread extends Thread {
private long i;
public long getI() {
return i;
}
public void setI(long i) {
this.i = i;
}
@Override
public void run() {
while (true) {
i++;
System.out.println(i);
}
}
}
启动类
package com.thread10;
public class Run {
public static void main(String[] args) {
try {
MyThread myThread = new MyThread();
myThread.start();
Thread.sleep(1000);
myThread.suspend();
System.out.println("main end");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
执行结果
207532
207533
207534
207535
207536
207537
207538
207539
207540
207541
//此处暂停,不继续输出
结论
出现这种情况得原因是,当程序运行到println()方法内部停止时,同步锁未被释放。
导致当前PrintStream对象得println()方法一直呈“暂停”状态,并且“锁未释放”,而main()方法中的代码
System.out.println("main end");
迟迟不能执行打印。
public void println(String x) {
synchronized (this) {
print(x);
newLine();
}
}
suspend与resume方法的缺点——不同步
在使用suspend和resume方法时也容易出现因为线程的暂停而导致数据不同步的情况,如下:
自定义共享变量类
package com.fiberhome.thread11;
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("停止a线程!");
Thread.currentThread().suspend(); //线程停止
}
this.password = p;
}
public void printUsernamePassword() {
System.out.println(username + " " + password);
}
}
启动类
package com.fiberhome.thread11;
public class Run {
public static void main(String[] args) throws InterruptedException {
//共享变量
final MyObject myObject = new MyObject();
//线程1
Thread thread1 = new Thread() {
@Override
public void run() {
myObject.setValue("a", "aa");
}
};
thread1.setName("a");
thread1.start();
Thread.sleep(500);
//线程2
Thread thread2 = new Thread() {
@Override
public void run() {
myObject.printUsernamePassword();
}
};
thread2.start();
}
}
执行结果
停止a线程!
a 11
结论
从输出结果看,共享对象数据没有同步。如果同步,输出结果应该为 a aa