算法_创建三个线程交替循环打印“A”、"B"、“C”

创建三个线程交替循环打印“A”、”B”、“C”

package com.xwl;
/**
 * 三个线程交替打印abc
 * @author Administrator
 *
 *主要的思想就是,为了控制执行的顺序,必须要先持有prev锁,也就是前一个线程要释放自身对象锁,再去申请自身对象锁,
 *两者兼备时打印字母,之后首先调用self.notifyAll()释放自身对象锁,唤醒下一个等待线程,再调用prev.wait()释放prev对象锁,终止当前线程,
 *等待循环结束后再次被唤醒。程序运行的主要过程就是A线程最先运行,持有C,A对象锁,后释放A,C锁,唤醒B。线程B等待A锁,再申请B锁,后打印B,
 *再释放B,A锁,唤醒C,线程C等待B锁,再申请C锁,后打印C,再释放C,B锁,唤醒A……
 */
public class ABC {
    //静态 类
    //线程 实现Runnable
    static class ThreadPrinter implements Runnable{ 
        private String name;//打印的内容
        private Object prev;//上一个线程持有的锁
        private Object self;//自己持有的锁
        //构造方法
        public ThreadPrinter(String name, Object prev, Object self) {
            super();
            this.name = name;
            this.prev = prev;
            this.self = self;
        }
        //任务
        public void run() { 
            //首先获取上一个线程的锁
            //然后再获取自己的锁
            //持有两把锁才能打印AorBorC
            //打印完了之后首先释放自己的所标记 self.notifyAll();
            //然后释放上一个线程的所标记 prev.wait();        
            while (true) {//多线程并发,不能用if,必须用循环测试等待条件,避免虚假唤醒
                synchronized (prev) {    // 先获取 prev 锁
                    synchronized (self) {// 再获取 self 锁
                        System.out.print(name);
                        self.notifyAll();// 先释放 self,唤醒其他线程竞争self锁
                    }
                    try {                   
                        prev.wait();     // 再释放 prev,休眠等待唤醒
                        /**
                         * 注意的是notify()调用后,并不是马上就释放对象锁,而是在相应的synchronized(){}语句块执行结束,自动释放锁,
                         * JVM会在wait()对象锁的线程中随机选取一线程,赋予其对象锁,唤醒线程,继续执行。
                         */
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }       
    //main
    public static void main(String[] args) throws InterruptedException {
        //首先创建锁标记
        Object a = new Object();
        Object b = new Object();
        Object c = new Object();      
        //三个任务       
        ThreadPrinter pa = new ThreadPrinter("A", c, a);
        ThreadPrinter pb = new ThreadPrinter("B", a, b);
        ThreadPrinter pc = new ThreadPrinter("C", b, c);        
        //创建三个线程分别把任务扔里面
        new Thread(pa).start();
        Thread.sleep(10);
        new Thread(pb).start();
        Thread.sleep(10);
        new Thread(pc).start();
        Thread.sleep(10);   
    }
}

第二种方式:

package com.xwl;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class TestABC {
    private static int state = 0;
    public static void main(String[] args) {
        final Lock lock = new ReentrantLock();
        Thread A = new Thread(new Runnable(){
            public void run() {
                while(state<=30){
                    lock.lock();
                    if(state%3 == 0){
                        System.out.println('A');
                        state++;
                    }
                    lock.unlock();
                }
            }
            });
        Thread B = new Thread(new Runnable(){
            public void run() {
                while(state<=30){
                    lock.lock();
                    if(state%3 == 1){
                        System.out.println('B');
                        state++;
                    }
                    lock.unlock();
                }
            }
            });
        Thread C = new Thread(new Runnable(){
            public void run() {
                while(state<=30){
                    lock.lock();
                    if(state%3 == 2){
                        System.out.println('C');
                        state++;
                    }
                    lock.unlock();
                }
            }
            });
        A.start();
        B.start();
        C.start();
    }
}

猜你喜欢

转载自blog.csdn.net/xwl_java/article/details/82079826