中断
public static boolean interrupted() {
return currentThread().isInterrupted(true);
}
可以看到interrupted返回的是当前调用线程的中断状态
public class Test {
public static void main(String[] args) throws InterruptedException{
Thread thread=new Thread(new Runnable() {
@Override
public void run() {
for(;;){}
}
});
thread.start();
System.out.println(thread.isInterrupted());
thread.interrupt();
System.out.println(thread.isInterrupted());
System.out.println(thread.interrupted());
System.out.println(Thread.interrupted());
System.out.println(thread.isInterrupted());
}
}
false
true // 还是中断状态
false // 此处是主线程的中断状态
false
true
wait/park/sleep/await/yield/join
public class Test {
public static void main(String[] args) throws InterruptedException {
Integer a = 3; // 共享变量
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
synchronized (a) {
try {
System.out.println("before wait "+System.currentTimeMillis());
a.wait(); // 调用了wait(0)
System.out.println("wait is ending "+System.currentTimeMillis());
} catch (Exception e) {
}
}
}
});
thread.start();
Thread.sleep(2000);
synchronized (a) {
a.notify();
Thread.sleep(4000);
}
}
}
before wait 1561814784666
wait is ending 1561814790685 // 隔了6000ms
可以看到,首先子线程需要获得共享变量的Monitor,才能进行wait。再接着主线程需要获得Monitor才能进行notify。同时,notify后子线程并不能立刻运行,还是需要等获得Monitor才能从wait方法返回
public final native void wait(long timeout) throws InterruptedException;
wait源码如上图所示,timeout若是0,则只能等待notify唤醒。若不是0的正数时间,在时间范围内,若是没有notify,到时间就会不再等待,返回就绪状态等Monitor。
public class Test {
public static void main(String[] args) throws InterruptedException {
Thread thread=new Thread(new Runnable() {
@Override
public void run() {
System.out.println("before park "+System.currentTimeMillis());
LockSupport.park(); // 没有许可证第一次park会被阻塞
System.out.println("after park "+System.currentTimeMillis());
}
});
thread.start();
Thread.sleep(2000);
LockSupport.unpark(thread);
}
}
before park 1561816399926
after park 1561816401934 // 第一次park被阻塞2秒
接着是先unpark发许可证,再接park,会立刻返回
public class Test {
public static void main(String[] args) throws InterruptedException {
Thread thread=new Thread(new Runnable() {
@Override
public void run() {
// LockSupport.unpark(thread);
LockSupport.unpark(Thread.currentThread()); // 注意这里边应该是当前线程,运行时确定
System.out.println("before park "+System.currentTimeMillis());
LockSupport.park(); // 没有许可证第一次park会被阻塞
System.out.println("after park "+System.currentTimeMillis());
}
});
thread.start();
}
}
before park 1561817436822
after park 1561817436822 // 立刻返回
CountDownLatch/CyclicBarrier
public class Test implements Runnable{
static final CountDownLatch end=new CountDownLatch(10);
static final Test TEST=new Test();
@Override
public void run() {
try {
System.out.println("test");
end.countDown(); // 计数器减一
}
catch (Exception e){
e.printStackTrace();
}
}
public static void main(String[] args) throws InterruptedException {
ExecutorService exec= Executors.newFixedThreadPool(10);
for(int i=0;i<10;i++){
exec.submit(TEST);
}
end.await(); // 主线程等待所有线程执行完成
System.out.println("okok");
exec.shutdown();
}
}
test
test
test
test
test
test
test
test
test
test
okok