题目描述
建立三个线程A、B、C,A线程打印10次字母A,B线程打印10次字母B,C线程打印10次字母C,但是要求三个线程同时运行,并且实现交替打印,即按照ABCABCABC的顺序打印。
5种方法
使用synchronized, wait和notifyAll
使用Lock->ReentrantLock 和 state标志
使用Lock->ReentrantLock 和Condition(await 、signal、signalAll)
使用Semaphore
使用AtomicInteger
扩展:采用join实现(一次性打印)
5.1 使用synchronized, wait和notifyAll
public classABC7 {private static Object o = new Object();//所对象
private static int state = 0;//控制顺序
private static int PRINT_NUMBER = 10;//打印次数
private static int THREAD_NUM = 3;//线程数量
static class ThreadGenetic implementsRunnable {charname;intdata;public ThreadGenetic(char name, intdata){this.name =name;this.data =data;
}public voidrun() {synchronized(o) {for(int i = 0; i
System.out.print(name);++state;
i++;//注意保证迭代次数
o.notifyAll();
}else{try{
o.wait();
}catch(InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
}public static voidmain(String[] args) {new Thread(new ThreadGenetic('B',1)).start();new Thread(new ThreadGenetic('A',0)).start();new Thread(new ThreadGenetic('C',2)).start();
}
}
5.2 使用Lock->ReentrantLock 和 state标志
importjava.util.concurrent.locks.ReentrantLock;public classABC {private static int state = 0;//控制顺序
private static int PRINT_NUMBER = 10;//打印次数
private static int THREAD_NUM = 3;//线程数量
private static ReentrantLock lock = new ReentrantLock();//锁
static class ThreadGenetic extendsThread{charname;intdata;public ThreadGenetic(char name, intdata){this.name =name;this.data =data;
}public voidrun(){for (int i = 0; i < PRINT_NUMBER; ) {//确保打印次数
lock.lock();if(state % THREAD_NUM == this.data){//确保按顺序打印
System.out.print(this.name);
state++; //确保按顺序打印
i++; //确保打印次数
}
lock.unlock();
}
}
}public static voidmain(String[] args) {new ThreadGenetic('B',1).start();new ThreadGenetic('C',2).start();new ThreadGenetic('A',0).start();
}
}
5.3 使用Lock->ReentrantLock 和Condition(await 、signal、signalAll)
方法1
importjava.util.concurrent.locks.Condition;importjava.util.concurrent.locks.ReentrantLock;public classABC8 {private static int state = 0;//控制顺序
private static int PRINT_NUMBER = 10;//打印次数
private static int THREAD_NUM = 3;//线程数量
private static ReentrantLock lock = new ReentrantLock();//锁
private static Condition condition =lock.newCondition();static class ThreadGenetic extendsThread{charname;intdata;public ThreadGenetic(char name, intdata){this.name =name;this.data =data;
}public voidrun(){
lock.lock();try{for (int i = 0; i < PRINT_NUMBER; ) {//确保打印次数
while(state % THREAD_NUM != data){//确保按顺序打印
condition.await();
}
System.out.print(name);
state++; //确保按顺序打印
i++; //确保打印次数
condition.signalAll();
}
}catch(InterruptedException e) {//TODO Auto-generated catch block
e.printStackTrace();
}
lock.unlock();
}
}public static voidmain(String[] args) {new ThreadGenetic('B',1).start();new ThreadGenetic('C',2).start();new ThreadGenetic('A',0).start();
}
}
方法2
importjava.util.concurrent.locks.Condition;importjava.util.concurrent.locks.ReentrantLock;public classABC2 {private static int state = 0;//控制顺序
private static int PRINT_NUMBER = 10;//打印次数
private static int THREAD_NUM = 3;//线程数量
private static ReentrantLock lock = new ReentrantLock();//锁
private static Condition conditionA =lock.newCondition();private static Condition conditionB =lock.newCondition();private static Condition conditionC =lock.newCondition();static class ThreadGenetic extendsThread{charname;intdata;
Condition condition1;
Condition condition2;public ThreadGenetic(char name, intdata, Condition condition1,Condition condition2){this.name =name;this.data =data;this.condition1 =condition1;this.condition2 =condition2;
}public voidrun(){
lock.lock();try{for (int i = 0; i < PRINT_NUMBER; ) {//确保打印次数
while(state % THREAD_NUM != data){//确保按顺序打印
condition1.await();
}
System.out.print(name);
state++; //确保按顺序打印
i++; //确保打印次数
condition2.signal();
}
}catch(InterruptedException e) {//TODO Auto-generated catch block
e.printStackTrace();
}
lock.unlock();
}
}public static voidmain(String[] args) {new ThreadGenetic('B',1,conditionB,conditionC).start();new ThreadGenetic('C',2,conditionC,conditionA).start();new ThreadGenetic('A',0,conditionA,conditionB).start();
}
}
5.4 使用Semaphore
importjava.util.concurrent.Semaphore;public classABC3 {private static int PRINT_NUMBER = 10;//打印次数
private static Semaphore semaphoreA = new Semaphore(1);private static Semaphore semaphoreB = new Semaphore(1);private static Semaphore semaphoreC = new Semaphore(1);static class ThreadGenetic extendsThread{charname;intdata;
Semaphore semaphore1;
Semaphore semaphore2;public ThreadGenetic(charname, Semaphore semaphore1,Semaphore semaphore2){this.name =name;this.semaphore1 =semaphore1;this.semaphore2 =semaphore2;
}public voidrun(){for (int i = 0; i < PRINT_NUMBER; i++) {//确保打印次数
try{
semaphore1.acquire();
System.out.print(name);
semaphore2.release();
}catch(InterruptedException e) {
e.printStackTrace();
}
}
}
}public static voidmain(String[] args) {try{
semaphoreB.acquire();//保证A先于BC开始
semaphoreC.acquire();
}catch(InterruptedException e) {
e.printStackTrace();
}new ThreadGenetic('B',semaphoreB,semaphoreC).start();new ThreadGenetic('C',semaphoreC,semaphoreA).start();new ThreadGenetic('A',semaphoreA,semaphoreB).start();
}
}
5.5 使用AtomicInteger
importjava.util.concurrent.atomic.AtomicInteger;public classABC5 {private static AtomicInteger atomicinteger = new AtomicInteger(0);private static final int MAX_SYC_VALUE = 3 * 10;static class ThreadGenetic extendsThread {charname;intdata;public ThreadGenetic(char name, intdata) {this.name =name;this.data =data;
}public voidrun() {while (atomicinteger.get() < MAX_SYC_VALUE-1) {if (atomicinteger.get() % 3 ==data) {
System.out.print(name);
atomicinteger.getAndIncrement();
}
}
}
}public static voidmain(String[] args) {new ThreadGenetic('B', 1).start();new ThreadGenetic('C', 2).start();new ThreadGenetic('A', 0).start();
}
}
5.6 采用join实现(一次性打印)
public classABC6 {public static voidmain(String[] args) {//线程A
final Thread a = new Thread(newRunnable() {
@Overridepublic voidrun() {
System.out.println("A");
}
});//线程B
final Thread b = new Thread(newRunnable() {
@Overridepublic voidrun() {try{//执行b线程之前,加入a线程,让a线程执行
a.join();
}catch(InterruptedException e) {
e.printStackTrace();
}
System.out.println("B");
}
});//线程C
final Thread c = new Thread(newRunnable() {
@Overridepublic voidrun() {try{//执行c线程之前,加入b线程,让b线程执行
b.join();
}catch(InterruptedException e) {
e.printStackTrace();
}
System.out.println("C");
}
});//启动三个线程
a.start();
b.start();
c.start();
}
}