今天做韩老师的坦克大战项目时看到一个线程题奥,大意就是主线程里开两个线程,一个去不断打印数字,另一个去通过输入“Q”来中断这个线程,
class A implements Runnable{
private boolean loop = true;
public void setLoop(boolean loop){
this.loop = loop;
}
@Override
public void run() {
while (loop) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println((int) (Math.random() * (1 + 100)));
}
}
public static void main(String[] args) {
A a = new A();
new Thread(a).start();
}
}
class B implements Runnable {
A a = new A();
Scanner scanner = new Scanner(System.in);
String c = "i";
@Override
public void run() {
while(!c.equals("Q")){
c = scanner.next();
if (c.equals("Q")){
a.setLoop(false);
}
}
}
public static void main(String[] args) {
B b = new B();
new Thread(b).start();
}
}
这是我自己写的一版,这和题目要求不一样,因为题目是要求在main里面开两个嘛。
然后我这里就发现在B里面创建的A的实例a,通过a调用setLoop方法去改这个static属性loop的值去中断A线程的执行是不行的,类A里的loop值没变,折腾了一天这个鬼问题。
问了一下AI,给的解释也看不懂,它把static改成了volatile,然后我又去搜了一下这个关键字,
这个可见性。。。。
然后我又照着要求写了一版,区别好像仅仅就是在main线程里面开线程?
public class WorkText01 {
public static void main(String[] args) {
Thread01 thread01 = new Thread01();
Thread02 thread02 = new Thread02();
new Thread(thread01).start();
new Thread(thread02).start();
}
}
class Thread01 implements Runnable{
private static boolean loop = true;
public void setLoop(boolean loop){
this.loop = loop;
}
@Override
public void run() {
while (loop) {
try {
Thread.sleep(1500);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println((int) (Math.random() * (1 + 100)));
}
}
}
class Thread02 implements Runnable{
String a = "a";
Thread01 thread01 = new Thread01();
Scanner scanner = new Scanner(System.in);
@Override
public void run() {
while(!a.equals("Q")){
a = scanner.next();
if (a.equals("Q")){
thread01.setLoop(false);
}
}
}
}
这样是可以实现效果的。好像把两个线程放在主线程里面就可以避免不可见性?
希望来个好大哥解答一下