Java实现:编写一个程序,开启 3 个线程,这三个线程的 ID 分别为 A、B、C,每个线程将自己的 ID 在屏幕上打印 10 遍,要求输出的结果必须按顺序显示。如:ABCABCABC…… 依次递归

多线程的交替必然涉及到线程通信的问题。为了更直观的显示效果,打印轮数也打印出来,即每次打印完C后打印对应轮数打印效果如下:
Java实现:编写一个程序,开启 3 个线程,这三个线程的 ID 分别为 A、B、C,每个线程将自己的 ID 在屏幕上打印 10 遍,要求输出的结果必须按顺序显示。如:ABCABCABC…… 依次递归_第1张图片

1、使用同步方法,即synchronized关键字:

public class TestPrintABC1 {
	public static void main(String[] args) {
		ABCDemo1 emo = new ABCDemo1();

		new Thread(new Runnable() {
			@Override
			public void run() {
				for (int i = 0; i < 10; i++) {
					emo.printA();
				}
			}
		}, "A").start();

		new Thread(new Runnable() {
			@Override
			public void run() {
				for (int i = 0; i < 10; i++) {
					emo.printB();
				}
			}
		}, "B").start();

		new Thread(new Runnable() {
			@Override
			public void run() {
				for (int i = 0; i < 10; i++) {
					int loopCount = i + 1;
					emo.printC(loopCount);
				}
			}
		}, "C").start();
	}
}

class ABCDemo1 {
	private int flag = 1;// 控制当前执行的线程的标记

	public synchronized void printA() {// 打印A的方法
		while(flag!=1) {
			try {
				this.wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		System.out.print(Thread.currentThread().getName());
		flag=2;
		this.notifyAll();
	}
	
	public synchronized void printB() {// 打印B的方法
		while(flag!=2) {
			try {
				this.wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		System.out.print(Thread.currentThread().getName());
		flag=3;
		this.notifyAll();
	}
	
	public synchronized void printC(int loopCount) {// 打印C的方法
		while(flag!=3) {
			try {
				this.wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		System.out.println(Thread.currentThread().getName()+" 第"+loopCount+"轮");
		flag=1;
		this.notifyAll();
	}
		
}

2、使用重入锁Lock:

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class TestPrintABC {

	public static void main(String[] args) {
		ABCDemo emo = new ABCDemo();

		new Thread(new Runnable() {
			@Override
			public void run() {
				for (int i = 0; i < 10; i++) {
					emo.printA();
				}
			}
		}, "A").start();

		new Thread(new Runnable() {
			@Override
			public void run() {
				for (int i = 0; i < 10; i++) {
					emo.printB();
				}
			}
		}, "B").start();

		new Thread(new Runnable() {
			@Override
			public void run() {
				for (int i = 0; i < 10; i++) {
					int totalLoop = i + 1;
					emo.printC(totalLoop);
				}
			}
		}, "C").start();
	}
}

class ABCDemo {
	private char flag = 'a';// 控制当前执行的线程的标记
	// 使用同步锁的方式解决线程安全问题,flag是共享数据
	private Lock lock = new ReentrantLock();
	// 使用Condition接口的相关方法来实现线程通信
	private Condition condition1 = lock.newCondition();
	private Condition condition2 = lock.newCondition();
	private Condition condition3 = lock.newCondition();

	public void printA() {// 打印A的方法
		lock.lock();
		try {
			if (flag != 'a') {
				condition1.await();
			}

			System.out.print(Thread.currentThread().getName());

			flag = 'b';
			condition2.signal();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			lock.unlock();
		}
	}

	public void printB() {// 打印B的方法
		lock.lock();
		try {
			if (flag != 'b') {
				condition2.await();
			}

			System.out.print(Thread.currentThread().getName());

			flag = 'c';
			condition3.signal();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			lock.unlock();
		}
	}

	public void printC(int loopCount) {// 打印C的方法
		lock.lock();
		try {
			if (flag != 'c') {
				condition3.await();
			}

			System.out.println(Thread.currentThread().getName() + " 第" + loopCount + "轮");

			flag = 'a';
			condition1.signal();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			lock.unlock();
		}
	}
}

 

你可能感兴趣的:(Java,多线程,线程通信,多线程)