1.synchronized
lock爲鎖對象,order爲1表示線程1可以打印,爲2表示線程2可以打印,爲3表示線程3可以打印
num表示打印的次數
public class PrintThread(){
private static Object lock = new Object();
private static volatile Integer order = 1;
private static AtomicInteger num = null;
public static void main(String[] args){
Scanner in = new Scanner(System.in);
num = new AtomicInteger(in.nextInt());
Thread thread1 = new Thread() {
@Override
public void run() {
while (num.get() > 0) {
synchronized (lock){
if (num.get() > 0 && order == 1){
System.out.println("a");
order++;
}
}
}
}
};
Thread thread2 = new Thread() {
@Override
public void run() {
while (num.get() > 0) {
synchronized (lock){
if (num.get() > 0 && order == 2){
System.out.println("l");
order++;
}
}
}
}
};
Thread thread3 = new Thread() {
@Override
public void run() {
while (num.get() > 0) {
synchronized (lock){
if (num.get() > 0 && order == 3){
System.out.println("i");
order = 1;
num.decrementAndGet();
}
}
}
}
};
thread1.start();
thread2.start();
thread3.start();
}
}
2.通過ReentrantLock上三個condition 和order變量
class PrintTest {
Scanner in = new Scanner(System.in);
private static ReentrantLock lock = new ReentrantLock();
private static Condition A = lock.newCondition();
private static Condition B = lock.newCondition();
private static Condition C = lock.newCondition();
private static volatile Integer order = 1;
private AtomicInteger num = new AtomicInteger(in.nextInt());
public static void main(String[] args) {
Thread thread1 = new Thread() {
@Override
public void run() {
while (num.get() > 0) {
lock.lock();
if (order != 1){
try {
C.await();
if (num.get() == 0) break; //不加該語句,則1,2線程會多打印一遍
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.print("a");
A.signal(); //喚醒等待在Acondition上的線程
order++;
lock.unlock();
}
}
};
Thread thread2 = new Thread() {
@Override
public void run() {
while (num.get() > 0 ){
lock.lock();
if (order != 2){
try {
A.await();
if (num.get() == 0) break;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.print("l");
B.signal();
order++;
lock.unlock();
}
}
};
Thread thread3 = new Thread() {
@Override
public void run() {
while (num.get() > 0) {
lock.lock();
if (order != 3){
try {
B.await();
if (num.get() == 0) break;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.print("i");
order = 1;
C.signal();
num.decrementAndGet();
lock.unlock();
}
}
};
thread1.start();
thread2.start();
thread3.start();
}
}
3.不使用任何鎖,進通過while循環
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
num = new AtomicInteger(in.nextInt());
Thread thread1 = new Thread() {
@Override
public void run() {
while (num.get() > 0) {
if (num.get() > 0 && order == 1) {
System.out.print("a");
order++;
}
}
}
};
Thread thread2 = new Thread() {
@Override
public void run() {
while (num.get() > 0) {
if (num.get() > 0 && order == 2) {
System.out.print("l");
order++;
}
}
}
};
Thread thread3 = new Thread() {
@Override
public void run() {
while (num.get() > 0) {
if (num.get() > 0 && order == 3) {
num.decrementAndGet(); //需要在order=1之前執行,否則thread1會多打印一個a
System.out.println("i");
order = 1;
}
}
}
};
thread1.start();
thread2.start();
thread3.start();
}
4.CountownLatch
public class PrinntThread{
private static AtomicInteger num = null;
/**
* 用於判斷線程一是否執行,倒計時設置爲1,執行後減1
*/
private static CountDownLatch c1 = new CountDownLatch(1);
/**
* 用於判斷線程二是否執行,倒計時設置爲1,執行後減1
*/
private static CountDownLatch c2 = new CountDownLatch(1);
/**
* 用於判斷線程3是否執行,倒計時設置爲1,執行後減1
*/
private static CountDownLatch c3 = new CountDownLatch(1);
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
num = new AtomicInteger(in.nextInt());
Thread thread1 = new Thread() {
@Override
public void run() {
while (num.get() > 0) {
try {
//等待c3倒計時,計時爲0則往下運行
c3.await();
if (num.get() > 0) System.out.println("a");
//對c2倒計時-1
c1.countDown();
c3 = new CountDownLatch(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
Thread thread2 = new Thread() {
@Override
public void run() {
while (num.get() > 0) {
try {
//等待c3倒計時,計時爲0則往下運行
c1.await();
if (num.get() > 0) System.out.println("l");
//對c2倒計時-1
c2.countDown();
c1 = new CountDownLatch(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
Thread thread3 = new Thread() {
@Override
public void run() {
while (num.get() > 0) {
try {
//等待c3倒計時,計時爲0則往下運行
c2.await();
if (num.get() > 0) System.out.println("i");
num.decrementAndGet();
//對c2倒計時-1
c3.countDown();
c2 = new CountDownLatch(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
thread1.start();
thread2.start();
thread3.start();
c3.countDown();
}
}