想到哪,写到哪,后期再整理
1.获取当前线程
Thread.currentThread()
2.线程阻塞相关方法(除开锁)
2.1 sleep
a) 方法一览
public static native void sleep(long millis) throws InterruptedException;
public static void sleep(long millis, int nanos)
throws InterruptedException {
//some method
sleep(millis);
}
b) 问题
- 我们代码中写入
Thread.sleep(200)
,在200ms后会立刻苏醒吗?
答:Thread.sleep会让线程立刻从runnable到block,但是从block到runnable,需要等待被调度!
join
join有三个重载方法,最后都是调 join(long millis)
所谓的join,可以本质是调用 currentThread().wait(millis);
注意经典模式 Thread.currentThread().join()
public final synchronized void join(long millis)
throws InterruptedException {
long base = System.currentTimeMillis();
long now = 0;
if (millis < 0) {
throw new IllegalArgumentException("timeout value is negative");
}
if (millis == 0) {
while (isAlive()) {//可能被唤醒
wait(0);
}
} else {
while (isAlive()) {//可能被唤醒
long delay = millis - now;
if (delay <= 0) {
break;
}
wait(delay);
now = System.currentTimeMillis() - base;
}
}
}
3 线程的停止
3.1 flag停止法
3.1.1 interrupt模式
a)方法一览
interrupt仅仅只是一个标记,不能直接打断线程
//true就会打断线程,并返回是否被线程状态,
//false则仅仅返回线程是否被打断
private native boolean isInterrupted(boolean ClearInterrupted);
//打断当前线程
public static boolean interrupted() {
return currentThread().isInterrupted(true);
}
//判断线程是否打断
public boolean isInterrupted() {
return isInterrupted(false);
}
//打断线程,其他线程可通过这个线程的句柄来打断
public void interrupt() {
if (this != Thread.currentThread())//如果不是当前线程则要判断是否有打断权限
checkAccess();
synchronized (blockerLock) {
Interruptible b = blocker;
if (b != null) {
interrupt0(); // Just to set the interrupt flag(这里我们可以看出 interrupt 仅仅是一个flag,并不能让线程停止)
b.interrupt(this);
return;
}
(
interrupt0();
}
b)注意点,处于阻塞状态下的线程
如果线程因为通过以下方法导致阻塞状态,将会抛出 InterruptedException
异常:
wait(),wait(long),wait(long, int)
join(),join(long),join(long, int) ,(本质因为wait导致)
sleep(long),sleep(long, int)
题目:执行完后会抛出打断异常吗?
public static void main(String[] args) {
Thread thread = new Thread(()->{
while (true);
});
thread.start();
new Thread(()->{
thread.interrupt();
}).start();
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
以上方法显然无法抛出异常,因为thread.join() 是wait main线程,而非wait thread的线程,所以无法打断!
需要注意,只有这个线程因为上述方法处于阻塞状态时,才会抛出打断异常!
c)总结 interrupt模式结束线程
如果线程被阻塞了,调用interrupt()
我们可以在try-catch方法里面结束线程,如果线程没有阻塞,那么我们可以通过调用isInterrupted()
来判断线程是否被打断,并结束线程
网友评论