【Java 多线程】Java 如何停止线程,
【Java 多线程】Java 如何停止线程,
总结如下几种方式使线程停止执行:
(1)共享bool类型变量方式;
(2)调用线程interrupt方式,同时通过isInterrupted方式判断线程是否被停止,若停止则终止循环操作(线程类中循环外没有其他操作);
(3)调用线程interrupt方式 + 抛出异常方式(循环外有其他操作情况);
(4)调用线程interrupt方式 + return方式(循环外有其他操作情况);
(5)将线程设置为守护线程,则所有非守护线程停止时,守护线程便结束;
下面对以上五种方式分别进行详细解释。
方法一:采用bool类型共享变量的方式
子线程与主线程共享一个实例对象,该对象中包含一个bool类型变量,可以在主线程中对该bool类型变量进行赋值,从而在子线程循环中通过判断该值确定是否继续;
注意:当有多个线程共享该变量时,考虑是否采用volatile关键字修饰该变量,保证所有线程读取到的变量为最新值;
参考代码如下:
package study20170304;
/**
* Created by apple on 17/3/4.
*/
public class MyObject {
volatile public boolean flag = true;
}
package study20170304;
/**
* Created by apple on 17/3/4.
*/
public class ThreadTest implements Runnable{
MyObject myObject = null;
public ThreadTest(MyObject myObject){
this.myObject = myObject;
}
@Override
public void run() {
while (myObject.flag){
}
System.out.println(Thread.currentThread().getId() + " 线程退出!");
}
}
package study20170304;
/**
* Created by apple on 17/3/4.
*/
public class Main {
public static void main(String[] args) {
MyObject myObject = new MyObject();
new Thread(new ThreadTest(myObject)).start();
try {
Thread.sleep(1000);
myObject.flag = false;//停止线程
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
package study20170304;
/**
* Created by apple on 17/3/4.
*/
public class Main {
public static void main(String[] args) {
MyObject myObject = new MyObject();
new Thread(new ThreadTest(myObject)).start();
try {
Thread.sleep(1000);
myObject.flag = false;//停止线程
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
最后运行结果为:
方法二:调用线程interrupt方式,同时通过isInterrupted方式判断线程是否被停止
与方法一类似,当线程循环外无其他语句时,外部调用该线程的interrupt方法,线程内部通过判断isInterrupted方式判断线程是否被停止从而终止循环;
参考代码如下:
package study20170304;
/**
* Created by apple on 17/3/4.
*/
public class ThreadTest extends Thread{
@Override
public void run() {
while (!this.isInterrupted()){
}
System.out.println(Thread.currentThread().getId() + " 线程退出!");
}
}
package study20170304;
/**
* Created by apple on 17/3/4.
*/
public class Main {
public static void main(String[] args) {
Thread thread = new ThreadTest();
thread.start();
try {
Thread.sleep(1000);
thread.interrupt();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
运行结果为:
方法三:当线程内部循环外仍有其他语句时,采用上述两种方法只能退出循环,而不能阻止循环外的语句执行。此时我们可以采取抛出异常的方式。当线程通过isInterrupted函数判断线程已被停止后,可以抛出异常InterruptedException来终止整个线程的执行。
参考代码如下:
package study20170304;
/**
* Created by apple on 17/3/4.
*/
public class ThreadTest extends Thread{
@Override
public void run() {
try {
int i = 5000000;
while (i>0){
System.out.println(i);
if (this.isInterrupted()){
System.out.println(Thread.currentThread().getId() + " 线程退出!");
throw new InterruptedException();
}
i--;
}
System.out.println(Thread.currentThread().getId() + " 线程继续执行");
} catch (InterruptedException e) {
e.printStackTrace();
System.out.println(Thread.currentThread().getId() + " 抛出异常,进入catch代码块");
}
}
}
package study20170304;
/**
* Created by apple on 17/3/4.
*/
public class Main {
public static void main(String[] args) {
Thread thread = new ThreadTest();
thread.start();
try {
Thread.sleep(1000);
thread.interrupt();
} catch (Exception e) {
e.printStackTrace();
}
}
}
此时程序运行结果为:
方法四:与方法三相同,只不过可以不抛出异常,而是直接return;但是《Java多线程编程核心技术》一书中写道:不过还是建议使用“抛异常”法来实现线程的停止,因为在catch块中可以对异常的信息进行相关的处理,而且实用异常流能更好、更方便的控制程序的运行流程,不至于代码中出现很多个return;造成污染。
方法五:将一个线程设置为守护线程后,当进程中没有非守护线程后,守护线程自动结束;
如下代码,在main函数中将ThreadTest线程设置为守护线程,则main函数所在主线程执行完毕后,守护线程也结束;
参考代码如下:
package study20170304;
/**
* Created by apple on 17/3/4.
*/
public class Main {
public static void main(String[] args) {
Thread thread = new ThreadTest();
thread.setDaemon(true);
thread.start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
相关文章
- 暂无相关文章
用户点评