使用interrupt来通知,而不是强制
java提供了interrrupt让一个线程来通知另一个线程停止
如果想中断一个线程,但是那个线程不想去中断,那就无能为力,我们没有强制去中断线程的手段,因为线程停止前需要做一定的收尾工作
所以正确停止线程,是如何用interrupt来通知那个线程,以及被停止的线程如何进行配合
public class stopThreadWithoutSleep implements Runnable{
public static void main(String[] args) throws InterruptedException {
Thread thread = new Thread(new stopThreadWithoutSleep());
thread.start();
Thread.sleep(1000);
thread.interrupt();
}
@Override
public void run() {
int num = 0;
while(num <= Integer.MAX_VALUE / 2) {
if (num % 10000 == 0) {
System.out.println(num + "是10000的倍数");
}
num++;
}
System.out.println("结束");
}
}
/*
由于太长,只展示结尾部分的结果
1073710000是10000的倍数
1073720000是10000的倍数
1073730000是10000的倍数
1073740000是10000的倍数
结束
* */
public class stopThreadWithoutSleep implements Runnable{
public static void main(String[] args) throws InterruptedException {
Thread thread = new Thread(new stopThreadWithoutSleep());
thread.start();
Thread.sleep(1000);
thread.interrupt();
}
@Override
public void run() {
int num = 0;
while(!Thread.currentThread().isInterrupted() && num <= Integer.MAX_VALUE / 2) {
if (num % 10000 == 0) {
System.out.println(num + "是10000的倍数");
}
num++;
}
System.out.println("结束");
}
}
/*
由于太长,只展示结尾部分的结果
587830000是10000的倍数
587840000是10000的倍数
587850000是10000的倍数
587860000是10000的倍数
结束
* */
public class stopThreadWithSleep {
public static void main(String[] args) {
Runnable runnable = () -> {
int num = 0;
while (num <= 300 && !Thread.currentThread().isInterrupted()) {
if (num % 100 == 0) {
System.out.println(num + "是100的倍数");
}
num++;
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
};
Thread thread = new Thread(runnable);
thread.start();
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
thread.interrupt();
}
}
/*
* 0是100的倍数
100是100的倍数
200是100的倍数
300是100的倍数
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at com.jx.JavaTest.stopThread.stopThreadWithSleep.lambda$main$0(stopThreadWithSleep.java:15)
at java.lang.Thread.run(Thread.java:748)
* */
public class stopThreadWithSleepEveryLoop {
public static void main(String[] args) {
Runnable runnable = () -> {
int num = 0;
try {
while (num <= 10000) {
if (num % 100 == 0) {
System.out.println(num + "是100的倍数");
}
num++;
Thread.sleep(10);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
};
Thread thread = new Thread(runnable);
thread.start();
try {
Thread.sleep(5000);
} catch (
InterruptedException e) {
e.printStackTrace();
}
thread.interrupt();
}
}
/*
* 0是100的倍数
100是100的倍数
200是100的倍数
300是100的倍数
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at com.jx.JavaTest.stopThread.stopThreadWithSleepEveryLoop.lambda$main$0(stopThreadWithSleepEveryLoop.java:15)
at java.lang.Thread.run(Thread.java:748)
Process finished with exit code 0
*
* */
public class CantInterrupt {
public static void main(String[] args) {
Runnable runnable = () -> {
int num = 0;
while (num <= 10000) {
if (num % 100 == 0) {
System.out.println(num + "是100的倍数");
}
num ++;
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
Thread thread = new Thread(runnable);
thread.start();
try {
Thread.sleep(5000);
} catch (
InterruptedException e) {
e.printStackTrace();
}
thread.interrupt();
}
}
/*
* 0是100的倍数
100是100的倍数
200是100的倍数
300是100的倍数
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at com.jx.JavaTest.stopThread.CantInterrupt.lambda$main$0(CantInterrupt.java:14)
at java.lang.Thread.run(Thread.java:748)
400是100的倍数
500是100的倍数
600是100的倍数
700是100的倍数
800是100的倍数
900是100的倍数
Process finished with exit code -1
* */
public class CantInterrupt {
public static void main(String[] args) {
Runnable runnable = () -> {
int num = 0;
while (num <= 10000 && !Thread.currentThread().isInterrupted()) {
if (num % 100 == 0) {
System.out.println(num + "是100的倍数");
}
num++;
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
Thread thread = new Thread(runnable);
thread.start();
try {
Thread.sleep(5000);
} catch (
InterruptedException e) {
e.printStackTrace();
}
thread.interrupt();
}
}
/*
0是100的倍数
100是100的倍数
200是100的倍数
300是100的倍数
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at com.jx.JavaTest.stopThread.CantInterrupt.lambda$main$0(CantInterrupt.java:14)
at java.lang.Thread.run(Thread.java:748)
400是100的倍数
500是100的倍数
Process finished with exit code -1
* */
public class StopThreadInProd implements Runnable{
public static void main(String[] args) throws InterruptedException {
Thread thread = new Thread(new StopThreadInProd());
thread.start();
Thread.sleep(1000);
thread.interrupt();
}
@Override
public void run() {
while (true) {
System.out.println("start");
try {
throwInMethod();
} catch (InterruptedException e) {
System.out.println("保存日志/关闭程序");
e.printStackTrace();
}
}
}
private void throwInMethod() throws InterruptedException {
Thread.sleep(2000);
}
}
/*
* start
保存日志/关闭程序
start
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at com.jx.JavaTest.stopThread.StopThreadInProd.throwInMethod(StopThreadInProd.java:26)
at com.jx.JavaTest.stopThread.StopThreadInProd.run(StopThreadInProd.java:17)
at java.lang.Thread.run(Thread.java:748)
start
start
Process finished with exit code -1
*
* */
public class StopThreadInProd2 implements Runnable{
public static void main(String[] args) throws InterruptedException {
Thread thread = new Thread(new StopThreadInProd2());
thread.start();
Thread.sleep(1000);
thread.interrupt();
}
@Override
public void run() {
while (true) {
if (Thread.currentThread().isInterrupted()) {
System.out.println("Interrupt");
break;
}
reInterrupt();
}
}
private void reInterrupt() {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
e.printStackTrace();
}
}
}
/*
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at com.jx.JavaTest.stopThread.StopThreadInProd2.reInterrupt(StopThreadInProd2.java:25)
at com.jx.JavaTest.stopThread.StopThreadInProd2.run(StopThreadInProd2.java:19)
at java.lang.Thread.run(Thread.java:748)
Interrupt
*
* */
public class StopThreadInProd2 implements Runnable{
public static void main(String[] args) throws InterruptedException {
Thread thread = new Thread(new StopThreadInProd2());
thread.start();
Thread.sleep(1000);
thread.interrupt();
}
@Override
public void run() {
while (true) {
if (Thread.currentThread().isInterrupted()) {
System.out.println("Interrupt");
break;
}
reInterrupt();
}
}
private void reInterrupt() {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// Thread.currentThread().interrupt();
e.printStackTrace();
}
}
}
/*
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at com.jx.JavaTest.stopThread.StopThreadInProd2.reInterrupt(StopThreadInProd2.java:25)
at com.jx.JavaTest.stopThread.StopThreadInProd2.run(StopThreadInProd2.java:19)
at java.lang.Thread.run(Thread.java:748)
*
* */
public class StopThread implements Runnable{
@Override
public void run() {
// 模拟指挥军队,一共五个连队,每个连队一百人
// 以连队为单位发放武器
for (int i = 0; i < 5; i++) {
System.out.println("连队" + i + "领取武器");
for (int j = 0; j < 10; j++) {
System.out.println(j);
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("连队" + i + "领取完毕");
}
}
public static void main(String[] args) {
Thread thread = new Thread(new StopThread());
thread.start();
try {
thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
thread.stop();
}
}
/*
* 连队0领取武器
0
1
2
3
4
5
6
7
8
9
连队0领取完毕
连队1领取武器
0
1
2
3
4
5
Process finished with exit code 0
* */
public class Volatile implements Runnable {
private volatile boolean canceled = false;
@Override
public void run() {
int num = 0;
try {
while (num <= 10000 && !canceled) {
if (num % 100 == 0) {
System.out.println(num + " 是100的倍数");
}
num++;
Thread.sleep(1);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) throws InterruptedException {
Volatile v = new Volatile();
Thread thread = new Thread(v);
thread.start();
Thread.sleep(1000);
v.canceled = true;
}
}
/*
*0 是100的倍数
100 是100的倍数
200 是100的倍数
300 是100的倍数
400 是100的倍数
500 是100的倍数
600 是100的倍数
Process finished with exit code 0
*
* */
// 模拟生产者和消费者
public class cantStop {
public static void main(String[] args) throws InterruptedException {
// 阻塞队列
// 满了之后,放不进去
// 空的时候取数据,也会堵塞
ArrayBlockingQueue storage = new ArrayBlockingQueue(10);
Producer producer = new Producer(storage);
Thread producerThread = new Thread(producer);
producerThread.start();
Thread.sleep(1000);
Consumer consumer = new Consumer(storage);
while (consumer.needMore()) {
System.out.println(consumer.storage.take() + "被消费");
Thread.sleep(100);
}
System.out.println("消费者不需要更多数据");
// 消费者不需要数据,让生产者停下来
producer.canceled = true;
}
}
// 生产者
class Producer implements Runnable {
public volatile boolean canceled = false;
BlockingQueue storage;
public Producer(BlockingQueue storage) {
this.storage = storage;
}
@Override
public void run() {
int num = 0;
try {
while (num <= 10000 && !canceled) {
if (num % 100 == 0) {
// 当堵塞队列满了之后,会堵塞在这里,而这段代码没有判断机制
storage.put(num);
System.out.println("num" + "生产");
}
num++;
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
System.out.println("生产者停止运行");
}
}
}
// 消费者
class Consumer {
BlockingQueue storage;
public Consumer(BlockingQueue storage) {
this.storage = storage;
}
public boolean needMore() {
if (Math.random() > 0.9) {
return false;
}
return true;
}
}
/*
* num生产
num生产
num生产
num生产
num生产
num生产
num生产
num生产
num生产
num生产
0被消费
num生产
消费者不需要更多数据
*
* */
public class finxed {
public static void main(String[] args) throws InterruptedException {
finxed finxed = new finxed();
// 阻塞队列
// 满了之后,放不进去
// 空的时候取数据,也会堵塞
ArrayBlockingQueue storage = new ArrayBlockingQueue(10);
Producer producer = finxed.new Producer(storage);
Thread producerThread = new Thread(producer);
producerThread.start();
Thread.sleep(1000);
Consumer consumer = finxed.new Consumer(storage);
while (consumer.needMore()) {
System.out.println(consumer.storage.take() + "被消费");
Thread.sleep(100);
}
System.out.println("消费者不需要更多数据");
// 消费者不需要数据,让生产者停下来
producerThread.interrupt();
}
class Producer implements Runnable {
public volatile boolean canceled = false;
BlockingQueue storage;
public Producer(BlockingQueue storage) {
this.storage = storage;
}
@Override
public void run() {
int num = 0;
try {
while (num <= 10000 && !Thread.currentThread().isInterrupted()) {
if (num % 100 == 0) {
storage.put(num);
System.out.println("num" + "生产");
}
num++;
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
System.out.println("生产者停止运行");
}
}
}
class Consumer {
BlockingQueue storage;
public Consumer(BlockingQueue storage) {
this.storage = storage;
}
public boolean needMore() {
if (Math.random() > 0.9) {
return false;
}
return true;
}
}
}
/*
* 2100被消费
num生产
2200被消费
num生产
2300被消费
num生产
消费者不需要更多数据
生产者停止运行
java.lang.InterruptedException
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.reportInterruptAfterWait(AbstractQueuedSynchronizer.java:2014)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2048)
at java.util.concurrent.ArrayBlockingQueue.put(ArrayBlockingQueue.java:353)
at com.jx.JavaTest.stopThread.volatiledmo.finxed$Producer.run(finxed.java:51)
at java.lang.Thread.run(Thread.java:748)
Process finished with exit code 0
*
* */
public void interrupt() {
if (this != Thread.currentThread())
checkAccess();
synchronized (blockerLock) {
Interruptible b = blocker;
if (b != null) {
interrupt0(); // Just to set the interrupt flag
b.interrupt(this);
return;
}
}
interrupt0();
}
private native void interrupt0();
public class InterruptedTest {
public static void main(String[] args) throws InterruptedException {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
while (true) {
}
}
});
thread.start();
thread.interrupt();
// 获取中断标志
System.out.println(thread.isInterrupted()); // true
// 获取中断标志并重置
System.out.println(thread.interrupted()); //false
System.out.println(Thread.interrupted()); // false
System.out.println(thread.isInterrupted()); //true
thread.join();
System.out.println("over");
}
}