1.停止线程的几种方法
java.lang.Thread#suspend 暂停
java.lang.Thread#resume 恢复,恢复suspend的线程
java.lang.Thread#stop() 强制停止
java.lang.Thread#interrupt 设置停止标识位
java.util.concurrent.locks.LockSupport#park 和suspend类似
java.util.concurrent.locks.LockSupport#unpark 和resume类似
增加停止字段stop标识是否需要停止
2.使用过程中的注意点
1.suspend和resume将被废弃的原因
suspend不会释放锁资源,容易造成线程的死锁,suspend和resume顺序必须是suspend->resume,如果先调用resume,再调用suspend,会造成线程永远在暂停状态,而且suspend会导致资源无法释放,这些方法已经被jdk废弃,例子:
package com.dxc;
import java.util.Random;
/**
* @Author: ding
* @Date: 2020-06-13 10:54
*/
public class StopThreadTest {
private static class SubThread extends Thread{
private String desc;
public SubThread(String desc){
this.desc = desc;
}
@Override
public void run() {
System.out.println(desc+":"+new Random().nextDouble());
}
}
public static void main(String[] args) throws Exception{
SubThread thread1 = new SubThread("线程1");
thread1.start();
thread1.resume();
thread1.suspend();
}
}
结果是无法输出任何信息,线程一直在等待状态
2.LockSupport解决1可能出现的死锁问题
package com.dxc;
import java.util.Random;
import java.util.concurrent.locks.LockSupport;
/**
* @Author: ding
* @Date: 2020-06-13 10:54
*/
public class StopThreadTest {
private static class SubThread extends Thread{
private String desc;
public SubThread(String desc){
this.desc = desc;
}
@Override
public void run() {
try{
Thread.sleep(1000);
}catch (Exception ex){
}
LockSupport.park();
System.out.println(desc+":"+new Random().nextDouble());
}
}
public static void main(String[] args) throws Exception{
SubThread thread1 = new SubThread("线程1");
thread1.start();
LockSupport.unpark(thread1);
}
}
输出:
线程1:0.06508664303403233
3.stop函数废弃原因
stop会强制停止该线程,可能会导致数据不一致,会强制释放该线程所拥有的资源
package com.dxc;
import java.util.Random;
/**
* @Author: ding
* @Date: 2020-06-13 10:54
*/
public class StopThreadTest {
private static class SubThread extends Thread{
private String desc;
public SubThread(String desc){
this.desc = desc;
}
@Override
public void run() {
synchronized (StopThreadTest.class){
try{
Thread.sleep(1000);
}catch (Exception ex){
}
System.out.println(desc+":"+new Random().nextDouble());
}
}
}
public static void main(String[] args) throws Exception{
SubThread thread1 = new SubThread("线程1");
thread1.start();
thread1.stop();
SubThread thread2 = new SubThread("线程2");
thread2.start();
}
}
输出:
线程2:0.6889376859853867
线程1停止后,释放cpu资源,停止执行,线程2执行输出
4.interrupt
这个函数只是设置停止标识位,代码中需要根据标识位来判断程序的运行还是停止,而且wait,sleep等函数会影响此停止标识抛出异常,并清除该标识:
package com.dxc;
import java.util.Random;
/**
* @Author: ding
* @Date: 2020-06-13 10:54
*/
public class StopThreadTest {
private static class SubThread extends Thread{
private String desc;
public SubThread(String desc){
this.desc = desc;
}
@Override
public void run() {
while (!Thread.currentThread().isInterrupted()){
System.out.println(new Random().nextDouble());
}
}
}
public static void main(String[] args) throws Exception{
SubThread thread1 = new SubThread("线程1");
thread1.start();
}
}
wait和sleep函数会清除抛出异常并清除标识,例如:
package com.dxc;
import java.util.Random;
/**
* @Author: ding
* @Date: 2020-06-13 10:54
*/
public class StopThreadTest {
private static class SubThread extends Thread{
private String desc;
public SubThread(String desc){
this.desc = desc;
}
@Override
public void run() {
try {
Thread.sleep(1000);
}catch (Exception ex){
ex.printStackTrace();
}
System.out.println(Thread.currentThread().isInterrupted());
}
}
public static void main(String[] args) throws Exception{
SubThread thread1 = new SubThread("线程1");
thread1.start();
thread1.interrupt();
}
}
输出:
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at com.dxc.StopThreadTest$SubThread.run(StopThreadTest.java:23)
false
java.lang.Thread#interrupted 返回线程的上次的中断状态,并清除中断状态
调用interrupt后第一次调用interrupted会返回true,再次调用interrupted返回false,如果没有外部程序再调用interrupt则状态一直为false
5.增加stop字段表示是否需要停止
package com.dxc;
import java.util.Random;
/**
* @Author: ding
* @Date: 2020-06-13 10:54
*/
public class StopThreadTest {
private static class SubThread extends Thread{
private volatile boolean stop = true;
@Override
public void run() {
while (!stop){
}
System.out.println("stop!!!");
}
}
public static void main(String[] args) throws Exception{
SubThread thread1 = new SubThread();
thread1.start();
try {
Thread.sleep(3000);
}catch (Exception ex){
}
thread1.stop = true;
}
}
程序正常结束
网友评论