public class RunThread extends Thread {
private boolean isRunning = true;
private void setRunning(boolean isRunning) {
this.isRunning = isRunning;
}
@Override
public void run() {
System.out.println("进入run方法.....");
while (isRunning == true){
//TODO 操作内容
}
System.out.println("线程停止....");
}
public static void main(String[] args) throws InterruptedException {
RunThread runThread = new RunThread();
runThread.start();
Thread.sleep(2000);
runThread.setRunning(false);
System.out.println("isRunning已经被设置为false");
System.out.println("isRunning : "+ runThread.isRunning);
}
}
运行结果如下:
image.png可以发现结果中isRunning 已经是被设置为false 了,但是却发现线程并没有停止。这是什么原因?
可以看如下图:
image.png image.pngrunThread 本身只是一个变量而已,真正的线程是在start后才会开启。而在线程本身中的变量是存在于主内存中的,jdk5之后为了提高线程效率,每当新开一个线程都会去拷贝主内存的副本,放入每个线程独立的工作内存中,所以没有特殊情况,主内存中改变的值,并不会影响到线程。这也就解释了为什么isRunning 的值改变之后对线程没效果。
如果要解决这个变量共享的问题,可以使用volatile关键字进行修饰。
之后的运行结果:
image.png这下,对主内存的变量进行的修改就可以被线程所共享到了,并按照代码预期的进行停止。
多线程示例:
public class RunningDemo implements Runnable {
private volatile boolean bo = true;
public void setBo(boolean bo) {
this.bo = bo;
}
@Override
public void run() {
while (bo == true) {
}
System.out.println("运行结束");
}
public static void main(String[] args) throws InterruptedException {
RunningDemo runningDemo = new RunningDemo();
Thread thread = new Thread(runningDemo);
Thread thread2 = new Thread(runningDemo);
thread.start();
thread2.start();
Thread.sleep(10); //注意一定要先休眠一小会,不然可能主线程把对象的值改了,线程还没创建。导致之后线程创建的值一开始就是false
runningDemo.setBo(false);
System.out.println(runningDemo.bo);
}
}
网友评论