Java 中断线程

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

回到顶部