Java 中断线程
线程自然终止:自然执行完或抛出未处理异常
Java中有3种方法可以使正在运行的线程终止运行:
1.使用退出标志使线程正常退出;
2.使用stop()方法强行终止线程,但这个方法不推荐使用,因为stop()和suspend(),resume()一样,都是作废的方法,使用它们会发生不可预料的结果;stop()会导致线程不会正确释放资源,suspend()容易导致死锁
3.使用interrupt() 方法中断线程;
suspend()死锁例子:
public class SuspendTest1 {private static class SynchronizedObject {
public synchronized void printString() {
System.out.println("begin --");
if (Thread.currentThread().getName().equals("thread-a")) {
System.out.println("a线程 suspend..");
Thread.currentThread().suspend();
}
System.out.println("end ---");
}
}
public static void main(String[] args) {
try {
SynchronizedObject object = new SynchronizedObject();
Thread thread1 = new Thread() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName());
object.printString();
}
};
thread1.setName("thread-a");
thread1.start();
TimeUnit.SECONDS.sleep(1);
Thread thread2 = new Thread() {
@Override
public void run() {
System.out.println("thread2 start...");
object.printString();
System.out.println("thread2 end...");
}
};
thread2.setName("thread-b");
thread2.start();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
当thread2运行到thread2 start...后,一致阻塞,用jstack查看,如下:
"thread-b" #12 prio=5 os_prio=0 tid=0x000000001d169800 nid=0x8658 waiting for monitor entry [0x000000001ddcf000]java.lang.Thread.State: BLOCKED (on object monitor)
at com.example.SuspendTest1$SynchronizedObject.printString(SuspendTest1.java:12)
- waiting to lock <0x000000076b5a9568> (a com.example.SuspendTest1$SynchronizedObject)
at com.example.SuspendTest1$2.run(SuspendTest1.java:40)
Locked ownable synchronizers:
- None
线程状态转移图如下:
发现出现BLOCKED,在thread2调用object.printString()这里出现死锁;
出现这种情况是因为运行到println方法内部时,同步锁不释放;
public void println(String x) {synchronized (this) {
print(x);
newLine();
}
}
Java线程是协作式,而非抢占式
抢占式:现行进程在运行过程中,如果有重要或紧迫的进程到达(其状态必须为就绪),则现运行进程将被迫放弃处理器,系统将处理器立刻分配给新到达的进程;如打开任务管理器终止一个进程;
Java协作式:调用一个线程的 interrupt() 方法中断一个线程,并不是强行关闭这个线程,将线程的中断标志位置为true,线程是否中断,由线程本身决定(类似人与人打招呼,但是对方回不回你又是另一回事);如下:
FutureTask<String> future = new FutureTask<>(new MyCallable());Thread thread = new Thread(future);
thread.start();
thread.interrupt();
//如果异步任务还没有完成,那么get()会阻塞,直到任务完成后才返回结果
System.out.println(future.get());
这里线程的中断有线程本身决定的;
isInterrupted() 判定当前线程是否处于中断状态
static方法interrupted() 判定当前线程是否处于中断状态,同时中断标志位改为false
方法里如果抛出InterruptedException,线程的中断标志位会被复位成false,如果确实是需要中断线程,要求我们自己在catch语句块里再次调用interrupt();
以上是 Java 中断线程 的全部内容, 来源链接: utcz.com/z/391696.html