一、Thread.stop()
package currentDemo1;
/**
* @author Zhou
* @Date:creat Time 2017/8/21
* 不要使用sotp()去终止线程,Thread.stop()在结束线程时会直接终止线程,并会立即释放!!这个线程所持有的所有锁。
*/
public class StopThreadUnsafe {
public static User user=new User();
public static class User{
private int id;
private String name;
public User(){
id=0;
name="0";
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
}
public static class ChangeUserThread extends Thread{
//对外提供停止线程的方法,自行决定线程何时退出
volatile boolean stopme=false;//volatile关键字 保证变量一致性 !!!不保证原子性!!!
public void stopMe(){
stopme=true;
}
@Override
public void run(){
while (true){
//若调用线程stop将引起一致性问题
if(stopme){
System.out.println("由自己调用终止线程,这时线程还未获得对象锁,并不会影响对象一致性!");
break;
}
synchronized (user){//利用synchronized锁控制User对象一致性
int v=(int)(System.currentTimeMillis()/1000);
user.setId(v);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
user.setName(String.valueOf(v));
}
Thread.yield();//线程优先级谦让
}
}
}
public static class ReadUserThread extends Thread{
@Override
public void run(){
while (true){
synchronized (user){
if(user.getId()!=Integer.parseInt(user.getName())){
System.out.println("出现不一致问题!"+user.toString());
}
Thread.yield();//线程谦让
}
}
}
}
public static void main(String[] args) throws InterruptedException {
new ReadUserThread().start();
while(true){
ChangeUserThread t=new ChangeUserThread();
t.start();
Thread.sleep(150);
t.stopMe();
// t.stop();//线程直接停止,放开所有持有的锁,引起对象不一致!!
}
}
}
二、Thread.interrupt()
package currentDemo1;
import com.sun.org.apache.xpath.internal.SourceTree;
/**
* @author Zhou
* @Date:creat Time 2017/8/21
* interrupt 方法他会发送给线程一个通知,告知线程将要退出(设置标志位,中断标志位表示当前线程已经中断)
* 目标线程接到通知后由目标线程自己决定如何处理!从而避免了Thread.stop()的一致性问题。
*
* public void Thread.interrupt() 中断线程
* public boolean Thread.isInterrupted() 判断是否被中断
* public static boolean Thread.interrupted() 判断是否被中断,并清除当前中断状态!
*/
public class InterruptedDemo {
public static void main(String[] args) throws InterruptedException {
Thread t=new Thread(){
@Override
public void run(){
while (true){
if(Thread.currentThread().isInterrupted()){
System.out.println("线程中断生效");
break;//得到中断通知 自行处理!
}
Thread.yield();//谦让
}
}
};
t.start();
Thread.sleep(2000);
t.interrupt();//中断
Thread t2=new Thread(){
@Override
public void run(){
while (true){
if(Thread.currentThread().isInterrupted()){
System.out.println("线程中断生效");
break;//得到中断通知 自行处理!
}
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
System.out.println("睡眠时出现中断,抛出中断异常!");
/**
* 设置中断标志!!!!
* Thread.sleep()方法由于中断会抛出中断异常,并切会清除线程的中断标志!!!若不加处理,下次循环时线程还是未中断状态。
* 为了保证数据一致性及完整性,再次执行了interrupt方法。只有这样下次循环时才能发现线程被中断了!
*/
Thread.currentThread().interrupt();
}
Thread.yield();
}
}
};
t2.start();
Thread.sleep(2000);
t2.interrupt();
}
}