不要使用Thread.stop()
因为unsafe , 要停止一个线程 , 建议的做法一个线程轮询 一个boolean域 .
public class StopThread{
private static boolean stopRequested ;
public static void main(String[] args) throws InterruptedException{
Thread backgroundThread = new Thread(new Runnable(){
public void run(){
int i=0;
while(!stopRequested)
i++;
}
});
backgroundThread.start();
TimeUtil.SECONDS.sleep(1);
stoprequested = true ;
}
}
这个程序不会停止,因为后台程序永远在循环.
因为没有同步,就不能保证后台线程看到主线程对stopRequested的修改.
下面加上同步这里的同步不是为了互斥,而是是两个线程通信
public class StopThread1 {
private static boolean stop;
private static void setStop(){
stop = true ;
}
private static synchronized boolean getStop(){
return stop;
}
public static void main(String[] args) throws InterruptedException {
Thread backgroundThread = new Thread(new Runnable() {
public void run() {
int i = 0;
while (!getStop())
i++;
}
});
backgroundThread.start();
TimeUnit.SECONDS.sleep(1);
setStop();
}
}
volatile 通信 , 不能实现互斥
public class StopThread2 {
private static volatile boolean stop;
public static void main(String[] args) throws InterruptedException {
Thread backgroundThread = new Thread(new Runnable() {
public void run() {
int i = 0;
while (!stop)
i++;
}
});
backgroundThread.start();
TimeUnit.SECONDS.sleep(1);
stop = true;
}
}
++ / – 不是原子操作
private static volatile int nextSerizlNumber = 0;
public static int generateSerizlNumber(){
return nextSerialNumber ++ ;
}
首先读取值,写回新的值,如果第二个线程在第一个线程读取旧值时,写如了新的值,这将是安全性失败 safety failure .
修改
private static final AtomicLong nextSerialNum = new AtomicLong();
public static long generateSerialNumber(){
return nextSerialNum.getAndIncrement();
}
当多个线程共享可变数据的时候,每个读或写数据的线程都必须执行同步.