Java 线程停止的方法有三种目前学习到的。
- stop 方法。
- volatile 变量控制退出。
- interrupt 方法。
第一种方法官方不建议,这种停止方法会导致释放锁后线程工作来不及清理,从而会出现数据不一致。
第二种方法写了个代码学习,如下:
共享资源类:
package com.lenovo.plm.dms.p6;
public class Service {
private volatile boolean requestedStoppedFlag = false;
private long record;
private String lock = new String();
public Service(long record){
this.record = record;
}
public void execute(){
synchronized (lock) {
while(true){
if(requestedStoppedFlag){
return;
}
System.out.println(Thread.currentThread().getName() + " " +record++);
}
}
}
public void stop(){
synchronized(this){
requestedStoppedFlag = true;
System.out.println(Thread.currentThread().getName() + " " +record++);
}
}
}
线程类:
package com.lenovo.plm.dms.p6;
public class MyThread extends Thread {
private Service service;
public MyThread(Service service){
this.service = service;
}
@Override
public void run() {
service.execute();
}
}
执行类如下:
package com.lenovo.plm.dms.p6;
public class Main {
public static void main(String[] args) {
Service service = new Service(0);
MyThread t1 = new MyThread(service);
t1.start();
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
service.stop();
}
}
这里创建了两个线程并发执行。主线程等待3s后,执行停止方法。执行后,线程结束。
第三种方法是用interrupt。见代码。
先创建service 共享资源的类。
package com.lenovo.plm.dms.p7;
public class Service {
private long record;
private String lock = new String();
public Service(long record){
this.record = record;
}
public void execute(){
synchronized(lock){
while(true){
if(Thread.interrupted()){
return;
}
System.out.println(Thread.currentThread().getName() + " " + record++);
}
}
}
}
其次线程类
package com.lenovo.plm.dms.p7;
public class MyThread extends Thread {
private Service service;
public MyThread(Service service){
this.service = service;
}
@Override
public void run() {
// TODO Auto-generated method stub
super.run();
service.execute();
}
}
最后调用:
package com.lenovo.plm.dms.p7;
public class Main {
public static void main(String[] args) {
Service service = new Service(0);
MyThread t = new MyThread(service);
t.start();
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
t.interrupt();
try {
t.join();
Thread.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(t.isAlive());
}
}
执行结果是线程被停止了。
这三种方法理解如下:
第一种跳过。
第二种使用了volatile关键字,这个关键字可以保证线程每次读取该变量时,都是直接从主内存中读取,不会直接读线程内存中的值。这样,可以确保线程每次读到的值,都是最新的。因此有线程修改了这个变量,那么
当前执行的线程会马上知道,因此可以作为线程间通信的方法。
第三种使用了线程自身的方法来检查中断状态位。