/**
* 停止一个运行线程 & volatile
*/
public class StopThreadTest01 {
static volatile boolean flag=false;
public static void main(String[] args) {
new Thread(()->{
while (true){
if (flag){
System.out.println("stop...");
break;
}
try {
TimeUnit.MILLISECONDS.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("run...");
}
},"t1").start();
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
new Thread(()->{
flag=true;
},"t2").start();
}
}
/**
* 停止一个运行线程 & AtomicBoolean(原子类)
*/
public class StopThreadTest02 {
static AtomicBoolean flag= new AtomicBoolean(false);
public static void main(String[] args) {
new Thread(()->{
while (true){
if (flag.get()){
System.out.println("stop...");
break;
}
try {
TimeUnit.MILLISECONDS.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("run...");
}
},"t1").start();
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
new Thread(()->{
flag.set(true);
},"t2").start();
}
}
| API方法 | 说明 |
|---|---|
| public void interrupt() | 实例方法interrupt()仅仅是设置线程的中断状态为true,不会停止线程 |
| public static boolean interrupted() | 静态方法,Thread.interrupted();判断线程是否被中断,并清除当前中断状态 |
| public boolean isInterrupted() | 实例方法,判断当前线程是否被中断(通过检查中断标志位) |
/**
* 中断一个运行线程 & interrupt & isInterrupted
*/
public class InterruptThreadTest01 {
public static void main(String[] args) {
Thread t1 = new Thread(() -> {
while (true) {
if (Thread.currentThread().isInterrupted()) { //返回打断标识符true or false
System.out.println("stop...");
break;
}
System.out.println("run...");
}
}, "t1");
t1.start();
try {
TimeUnit.MILLISECONDS.sleep(20);
} catch (InterruptedException e) {
e.printStackTrace();
}
new Thread(()->{
t1.interrupt(); //将t1打断标识符置为true,并不会立即中断线程运行
},"t2").start();
}
}
/**
* 中断一个运行线程 & interrupt & isInterrupted
* 当线程处于 sleep | wait | join 方法时中断会 清除中断标识符,并抛出中断异常
* 解决方法:在 cathy块中重新打断 interrupt
*/
public class InterruptThreadTest02 {
public static void main(String[] args) {
Thread t1 = new Thread(() -> {
while (true) {
if (Thread.currentThread().isInterrupted()) { //返回打断标识符true or false
System.out.println("stop...");
break;
}
try {
Thread.sleep(200);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();//重新打断,否则不会中断线程运行
e.printStackTrace();
}
System.out.println("run...");
}
}, "t1");
t1.start();
try {
TimeUnit.MILLISECONDS.sleep(20);
} catch (InterruptedException e) {
e.printStackTrace();
}
new Thread(()->{
t1.interrupt(); //将t1打断标识符置为true,并不会立即中断线程运行
},"t2").start();
}
}
/**
* 中断一个运行线程 & Interrupted
* 返回当前中断标识符 true or false,并重置中断标识符 (false)
*/
public class InterruptThreadTest03 {
public static void main(String[] args) {
System.out.println(Thread.interrupted());//false
Thread.currentThread().interrupt(); //中断
System.out.println(Thread.interrupted());//true
System.out.println(Thread.interrupted());//false
}
}
/**
* wait() & notify() & notifyAll()
*/
public class WaitNotifyTest {
public static void main(String[] args) {
Object lock = new Object();
new Thread(()->{
synchronized (lock){
System.out.println("run...");
try {
lock.wait(); //wait,释放锁并进入等待队列
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("被唤醒。。。");
}
},"t1").start();
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
new Thread(()->{
synchronized (lock){
lock.notify(); //唤醒等待队列中的一个线程
}
},"t1").start();
}
}
/**
* ReentrantLock
* await() & signal() & signalAll()
*/
public class AwaitSignalTest {
public static void main(String[] args) {
ReentrantLock lock = new ReentrantLock();
Condition waitQueue = lock.newCondition();
new Thread(()->{
lock.lock(); //获得锁
try {
System.out.println("run...");
try {
waitQueue.await(); //await,释放锁并进入等待队列
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("被唤醒。。。");
} finally {
lock.unlock(); //释放锁
}
},"t1").start();
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
new Thread(()->{
lock.lock();
try {
waitQueue.signal(); //唤醒等待队列中的一个线程
} finally {
lock.unlock();
}
},"t1").start();
}
}
LockSupport类使用了一种名为Permit(许可)的概念来做到阻塞和唤醒线程的功能, 每个线程都有一个许可(permit), permit只有两个值1和零,默认是零。 可以把许可看成是一种(0,1)信号量(Semaphore),但与 Semaphore 不同的是,许可的累加上限是1。
/**
* LockSupport
* park() & unpark()
* 许可证数量只能是1,不可累加
*/
public class LockSupportTest {
public static void main(String[] args) {
Thread t1 = new Thread(() -> {
System.out.println("run...");
LockSupport.park(); //获得许可证,无将被阻塞
System.out.println("被唤醒。。。");
}, "t1");
t1.start();
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
new Thread(()->{
LockSupport.unpark(t1); //给线程t1发放许可证
},"t1").start();
}
}