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();
}
}