方法一:使用volatile修饰,保证线程间变量的可见性
public class ThreadPrintTest extends Thread{
//volatile修饰,保证线程可见性,这里不需要保证原子性,因为run有if判断
private volatile static int state=0;
private String name="ABC";
private int type;
public ThreadPrintTest(int type){
this.type=type;
}
public void run(){
for (int i = 0; i <10 ; ) {
if (state % 3 == type) {
System.out.println(name.charAt(type));
state++;
i++;
}
}
}
public static void main(String[] args) {
new ThreadPrintTest(0).start();
new ThreadPrintTest(1).start();
new ThreadPrintTest(2).start();
}
}
方法二:使用重入锁ReentrantLock,保证变量在线程间的原子性
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class ThreadPrintPlanB {
private static Lock lock=new ReentrantLock();
private static int state=0;//通过state的值来确定是哪个线程打印
static class ThreadA extends Thread{
public void run(){
for (int i = 0; i <10 ; ) {
try{
lock.lock();
while(state%3==0){// 多线程并发,不能用if,必须用循环测试等待条件,避免虚假唤醒
System.out.print("A");
state++;
i++;
}
}finally{
lock.unlock();
}
}
}
}
static class ThreadB extends Thread{
public void run(){
for (int i = 0; i <10 ; ) {
try{
lock.lock();
while(state%3==1){// 多线程并发,不能用if,必须用循环测试等待条件,避免虚假唤醒
System.out.print("B");
state++;
i++;
}
}finally{
lock.unlock();
}
}
}
}
static class ThreadC extends Thread{
public void run(){
for (int i = 0; i <10 ; ) {
try{
lock.lock();
while(state%3==2){// 多线程并发,不能用if,必须用循环测试等待条件,避免虚假唤醒
System.out.print("C");
state++;
i++;
}
}finally{
lock.unlock();
}
}
}
}
public static void main(String[] args) {
System.out.println("planB");
new ThreadA().start();
new ThreadB().start();
new ThreadC().start();
}
}
两种方式的结果:
ABCABCABCABCABCABCABCABCABCABC
Process finished with exit code 0
参考:https://blog.csdn.net/hefenglian/article/details/82596072