经典面试题之多线程顺序循环打印
这里先介绍几个简单的方法,其他后续补充。
1、利用volatile关键字保证可见性和有序性。
// 1、利用volatile关键字保证可见性和有序性。
private static int i=0, j=0, z=0;
private volatile static int next = 0;
public static void VolatileCase() {
new Thread(()->{
while(i<5) {
if(next==0) {
System.out.println(Thread.currentThread().getName()+" updating i to " + i++);
next = 1;
}
}
}, "I").start();
new Thread(()->{
while(j<5) {
if(next==1) {
System.out.println("J updating j to " + j++);
next = 2;
}
}
}, "J").start();
new Thread(()->{
while(z<5) {
if(next==2) {
System.out.println("Z updating z to " + z++);
next = 0;
}
}
}, "Z").start();
}
2、利用synchronized和wait、 notifyAll来实现。
private static Object o = new Object();
public static void SynchronizedCase() {
new Thread(()->{
while(i<5) {
synchronized(o) {
if(next==0) {
System.out.println("A updating i to " + i++);
next = 1;
o.notifyAll();
}else {
try {
o.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}, "A").start();
new Thread(()->{
while(j<5) {
synchronized(o) {
if(next==1) {
System.out.println("B updating j to " + j++);
next = 2;
o.notifyAll();
}else {
try {
o.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}, "B").start();
new Thread(()->{
while(z<5) {
synchronized(o) {
if(next==2) {
System.out.println("C updating z to " + z++);
next = 0;
o.notifyAll();
}else {
try {
o.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}, "C").start();
}
3、使用Lock达到与synchronized一样的效果。
private static Lock mylock = new ReentrantLock();
private static boolean flag = true;
public static void LockCase() {
new Thread(()->{
while(i<5) {
try {
mylock.lock();
while(flag) {
System.out.println("ii updating i to " + i++);
flag = false;
}
} catch (Exception e) {
e.printStackTrace();
} finally {
mylock.unlock();
}
}
}, "ii").start();
new Thread(()->{
while(z<5) {
try {
mylock.lock();
while(!flag) {
System.out.println("zz updating z to " + z++);
flag = true;
}
} catch (Exception e) {
e.printStackTrace();
} finally {
mylock.unlock();
}
}
}, "zz").start();
}