用三个线程循环输出ABC

前两天看Java吧有人求助这个问题。想了想并不是很难。今天就顺手实现了一下。

我自己想到的有两种方法,一个是使用synchronized,一个是使用lock。

一、synchronized

package com.test;

public class PrintABC {
    
    private static int count = 0;

    public static void main(String[] args) {
        String str = "ABC";
        PrintABC printABC = new PrintABC();
        ThreadA threadA = printABC.new ThreadA(str);
        ThreadB threadB = printABC.new ThreadB(str);
        ThreadC threadC = printABC.new ThreadC(str);
        threadA.start();
        threadB.start();
        threadC.start();
    }
    
    /**
     * 打印A
     * @author LKB
     *
     */
    class ThreadA extends Thread{
        
        private String str;
        
        public ThreadA(String str) {
            // TODO Auto-generated constructor stub
            this.str = str;
        }
        
        public void run(){
            while(count < 28){
                synchronized (str) {
                    if(count%3 == 0){
                        System.out.println("A");
                        count++;
                    }
                }
            }
        }       
    }
    
    /**
     * 打印B
     * @author LKB
     *
     */
    class ThreadB extends Thread{
        
        private String str;
        
        public ThreadB(String str) {
            // TODO Auto-generated constructor stub
            this.str = str;
        }
        
        public void run(){
            while(count < 29){
                synchronized (str) {
                    if(count%3 == 1){
                        System.out.println("B");
                        count++;
                    }
                }
            }
        }       
    }
    
    /**
     * 打印C
     * @author LKB
     *
     */
    class ThreadC extends Thread{
        
        private String str;
        
        public ThreadC(String str) {
            // TODO Auto-generated constructor stub
            this.str = str;
        }
        
        public void run(){
            while(count < 30){
                synchronized (str) {
                    if(count%3 == 2){
                        System.out.println("C");
                        System.out.println("++++++");
                        System.out.println("------");
                        count++;
                    }
                }
            }
        }       
    }
    

}

这个方法的关键是synchronized关键字的位置。把它放在while判断之下就OK了。如果把synchronized关键字放在while外,则一直在锁中无法跳出锁。

二、lock

package com.test;

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

public class PrintABC2 {
    
    private int count = 0;
    private Lock lock = new ReentrantLock();
    private Condition conditionA = lock.newCondition();
    private Condition conditionB = lock.newCondition();
    private Condition conditionC = lock.newCondition();
    
    public static void main(String[] args) {
        PrintABC2 printABC = new PrintABC2();
        ThreadA threadA = printABC.new ThreadA();
        ThreadB threadB = printABC.new ThreadB();
        ThreadC threadC = printABC.new ThreadC();
        threadA.start();
        threadB.start();
        threadC.start();
        
    }
    
    /**
     * 打印A
     * @author LKB
     *
     */
    class ThreadA extends Thread{
        
        public void run(){
            try {
                lock.lock();
                while(count < 30){
                    if (count%3 != 0) {
                        conditionA.await();
                    }
                    System.out.println("A");
                    count ++;
                    conditionB.signalAll();    
                }
            } catch (Exception e) {
                // TODO: handle exception
                e.printStackTrace();
            }finally {
                lock.unlock();
                System.out.println("ThreadA 中执行了 unlock");
            }
        }
    }
    
    /**
     * 打印B
     * @author LKB
     *
     */
    class ThreadB extends Thread{
        
        public void run(){
            try {
                lock.lock();
                while(count < 30){
                    if (count%3 != 1) {
                        conditionB.await();
                    }
                    System.out.println("B");
                    count ++;
                    conditionC.signalAll();                
                }
            } catch (Exception e) {
                // TODO: handle exception
                e.printStackTrace();
            }finally {
                lock.unlock();
                System.out.println("ThreadB 中执行了 unlock");
            }
        }
    }
    
    /**
     * 打印C
     * @author LKB
     *
     */
    class ThreadC extends Thread{
        
        public void run(){
            try {
                lock.lock();
                while(count < 30){
                    if (count%3 != 2) {
                        conditionC.await();
                    }
                    System.out.println("C");
                    System.out.println("+++++++");
                    System.out.println("-------");
                    count ++;
                    if(count < 30){
                        conditionA.signalAll();
                    }
                }
            } catch (Exception e) {
                // TODO: handle exception
                e.printStackTrace();
            }finally {
                lock.unlock();
                System.out.println("ThreadC 中执行了 unlock");
            }
        }
    }
    
}

lock方法相对而言就简单多了,不需要精妙地设计,只需要知道lock和condition的用法就好了。

在一个lock对象里可以创建多个Condition(即对象监视器)实例。线程对象可以注册到指定的Condition中,从而可以有选择性地进行线程通知。

 

posted on 2017-08-16 21:26  猫咪大王  阅读(1237)  评论(0编辑  收藏  举报