public class ThreadTest {
public static void main(String[] args) {
System.out.println("main: start");
MyRunnable runnable = new MyRunnable();
new Thread(runnable).start();
while (true) {
if (runnable.getFlag()) {
System.out.println("main: break");
break;
}
}
System.out.println("main: end");
}
}
class MyRunnable implements Runnable {
private boolean flag = false;
@Override
public void run() {
System.out.println("run: start");
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
flag = true;
System.out.println("run: end");
}
public boolean getFlag() {
return flag;
}
}
运行输出:
main: start
run: start
run: end
main: break和main:end并未输出,有哪些解决方案?
方案1:使用volatile关键字
给flag字段加上volatile关键字,可以保证多线程的可见性
public class ThreadTest {
public static void main(String[] args) {
System.out.println("main: start");
MyRunnable runnable = new MyRunnable();
new Thread(runnable).start();
while (true) {
if (runnable.getFlag()) {
System.out.println("main: break");
break;
}
}
System.out.println("main: end");
}
}
class MyRunnable implements Runnable {
private volatile boolean flag = false;
@Override
public void run() {
System.out.println("run: start");
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
flag = true;
System.out.println("run: end");
}
public boolean getFlag() {
return flag;
}
}
运行输出:
main: start
run: start
run: end
main: break
main: end
方案2:使用原子性操作
使用原子AtomicBoolean进行操作
import java.util.concurrent.atomic.AtomicBoolean;
public class ThreadTest {
public static void main(String[] args) {
System.out.println("main: start");
MyRunnable runnable = new MyRunnable();
new Thread(runnable).start();
while (true) {
if (runnable.getFlag()) {
System.out.println("main: break");
break;
}
}
System.out.println("main: end");
}
}
class MyRunnable implements Runnable {
private AtomicBoolean flag = new AtomicBoolean(false);
@Override
public void run() {
System.out.println("run: start");
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
flag.set(true);
System.out.println("run: end");
}
public boolean getFlag() {
return flag.get();
}
}
运行输出:
main: start
run: start
run: end
main: break
main: end
方案3:使用synchronized进行代码块同步
public class ThreadTest {
public static void main(String[] args) {
System.out.println("main: start");
MyRunnable runnable = new MyRunnable();
new Thread(runnable).start();
while (true) {
synchronized (ThreadTest.class) {
// 同步代码执行完,工作内存数据会更新到主内存
// 线程休眠,磁盘io等
}
if (runnable.getFlag()) {
System.out.println("main: break");
break;
}
}
System.out.println("main: end");
}
}
class MyRunnable implements Runnable {
private boolean flag = false;
@Override
public void run() {
System.out.println("run: start");
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
flag = true;
System.out.println("run: end");
}
public boolean getFlag() {
return flag;
}
}
运行输出:
main: start
run: start
run: end
main: break
main: end