题目描述:
- 问题描述:有4个线程和1个公共的字符数组。
- 线程1的功能就是向数组输出A,线程2的功能就是向字符输出B,线程3的功能就是向数组输出C,
- 线程4的功能就是向数组输出D。要求按顺序向数组赋值ABCDABCDABCD,ABCD的个数由线程函数1的参数指定
示例1
- 输入
10 - 输出
ABCDABCDABCDABCDABCDABCDABCDABCDABCDABCD
实现思路:
- 让A线程分配对象锁a,b。
- 让B线程分配对象锁b,c。
- 让C线程分配对象锁c,d。
- 让D线程分配对象锁d,a。
- 接下就是重点,我们会用Objcet类中的wait()方法和notify()方法。
- wait():等待,如果线程执行了wait方法,那么该线程会进入等待的状态,等待状态下的线程必须要被其他线程调用notify()方法才能唤醒。wait()方法执行后,当前线程释放锁,其他线程可以竞争该锁。
- notify()方法执行后,唤醒线程不会立刻释放锁,要等唤醒线程全部执行完毕后才释放对象锁。
- 我们要做的就是在A线程在执行打印“A”后,就唤醒B线程,然后让A线程进入等待。以此类推,B线程在执行打印“B”后,就唤醒C线程,然后让B线程进入等待。C线程在执行打印“C”后,就唤醒D线程,然后让C线程进入等待。D线程在执行打印“D”后,就唤醒A线程,然后让D线程进入等待。
- 这里有个问题我们在启动线程的时候为了确保A线程先打印,我们在初始化线程的时候在线程中增加了两个静态变量newIndex,runIndex。(静态变量的值是所有线程共享的)给线程分别制定相对应的id。id = newIndex++线程执行之后runIndex++。初始化A线程id为0,runIndex为0,B线程为1,runIndex为1,C线程为2,runIndex为2,D线程为3,runIndex为3,当id > runIndex 时说明这个线程是首次执行且还不应该到它执行打印,所以把它在外层synchronized的对象上休眠等待它上一个线程执行答应后唤醒它。
- 在判断此次打印不是最后一次后则让该线程进入等待。
package huaweijishi;
import java.util.Scanner;
public class test19 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
while (scanner.hasNext()){
int num = scanner.nextInt();
Object a = new Object();
Object b = new Object();
Object c = new Object();
Object d = new Object();
Thread thread1 = new Thread(new ThreadPrintAbcd("A",a,b,num));
Thread thread2 = new Thread(new ThreadPrintAbcd("B",b,c,num));
Thread thread3 = new Thread(new ThreadPrintAbcd("C",c,d,num));
Thread thread4 = new Thread(new ThreadPrintAbcd("D",d,a,num));
thread1.start();
thread2.start();
thread3.start();
thread4.start();
}
}
}
class ThreadPrintAbcd implements Runnable{
private static int newIndex=0;
private static int runIndex=0;
private boolean isFirstRun=true;
private Object self;
private Object next;
private String name;
private int id;
private int num;
public ThreadPrintAbcd(String name,Object self,Object next,int num){
id = newIndex++;
this.name = name;
this.self = self;
this.next = next;
this.num = num;
}
@Override
public void run() {
while (num > 0){
synchronized(self){
if(id > runIndex){
try {
self.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.print(name);
if(isFirstRun){
runIndex ++;
isFirstRun=false;
}
synchronized (next) {
next.notify();
}
num--;
if(num >0){
try {
self.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
}
运行结果
