• ABC三个线程交替打印10遍,要求A打印5次,B打印10次,C打印15次


    问题:

      ABC三个线程交替打印10遍,要求A打印5次,B打印10次,C打印15

     第一遍
    AAAAABBBBBBBBBBCCCCCCCCCCCCCCC
    第二遍
    AAAAABBBBBBBBBBCCCCCCCCCCCCCCC
    ...共打印10

    1.使用Sychronized+wait()+notify()的方式
    package com.yang.test;
    
    /**
     * ABC三个线程交替打印10遍,要求A打印5次,B打印10次,C打印15次
     * 第一遍
     * AAAAABBBBBBBBBBCCCCCCCCCCCCCCC
     * 第二遍
     * AAAAABBBBBBBBBBCCCCCCCCCCCCCCC
     * ...共打印10遍
     * @author yang yajun
     * @date 2020/12/2615:31
     */
    public class OrderThreadPrint {
    
        public static void main(String[] arg0){
            Print print = new Print();
    
            new Thread(()->{
                for (int i = 0; i < 10; i++) {
                    print.printA();
                }
            },"A").start();
            new Thread(()->{
                for (int i = 0; i < 10; i++) {
                    print.printB();
                }
            },"B").start();
            new Thread(()->{
                for (int i = 0; i < 10; i++) {
                    print.printC();
                }
            },"C").start();
        }
    }
    
    class Print{
        private int i = 1;
        public synchronized void  printA(){
            while (i%3!=1) {
                try {
                    wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            for (int j = 0; j < 5; j++) {
                System.out.print(Thread.currentThread().getName() + i);
            }
            i++;
            notifyAll();
        }
        public synchronized void  printB(){
            while (i%3!=2) {
                try {
                    wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            for (int j = 0; j < 10; j++) {
                System.out.print(Thread.currentThread().getName()+i);
            }
            i++;
            notifyAll();
        }
        public synchronized void  printC(){
            while (i%3!=0) {
                try {
                    wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            for (int j = 0; j < 15; j++) {
                System.out.print(Thread.currentThread().getName() + i);
            }
            i++;
            notifyAll();
        }
    
    }
    
    2.使用Lock(Condition)+await()+signal()来实现
    package com.yang.test;
    
    import java.util.concurrent.locks.Condition;
    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReentrantLock;
    
    /**
     * ABC三个线程交替打印10遍,要求A打印5次,B打印10次,C打印15次
     * 第一遍
     * AAAAABBBBBBBBBBCCCCCCCCCCCCCCC
     * 第二遍
     * AAAAABBBBBBBBBBCCCCCCCCCCCCCCC
     * ...共打印10遍
     * @author yang yajun
     * @date 2020/12/2615:31
     */
    public class OrderThreadPrintLock {
    
        public static void main(String[] arg0){
            PrintLk print = new PrintLk();
    
            new Thread(()->{
                for (int i = 0; i < 10; i++) {
                    print.printA();
                }
            },"A").start();
            new Thread(()->{
                for (int i = 0; i < 10; i++) {
                    print.printB();
                }
            },"B").start();
            new Thread(()->{
                for (int i = 0; i < 10; i++) {
                    print.printC();
                }
            },"C").start();
        }
    }
    
    class Print{
        private int i = 1;
        private Lock lock = new ReentrantLock();
        private Condition condition1 = lock.newCondition();
        private Condition condition2 = lock.newCondition();
        private Condition condition3 = lock.newCondition();
    
        public synchronized void  printA(){
            lock.lock();
            try {
                while (i!=1) {//判断,多线程通信,使用while代替if
                    try {
                        condition1.await();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            //干活 for (int j = 0; j < 5; j++) { System.out.print(Thread.currentThread().getName() + i); } i=2; condition2.signal();//通知 }finally { lock.unlock(); } } public synchronized void printB(){ lock.lock(); try { while (i!=2) { try { condition2.await(); } catch (InterruptedException e) { e.printStackTrace(); } } for (int j = 0; j < 10; j++) { System.out.print(Thread.currentThread().getName()+i); } i=3; condition3.signal(); }finally { lock.unlock(); } } public synchronized void printC(){ lock.lock(); try { while (i!=3) { try { condition3.await(); } catch (InterruptedException e) { e.printStackTrace(); } } for (int j = 0; j < 15; j++) { System.out.print(Thread.currentThread().getName() + i); } i=1; condition1.signal(); }finally { lock.unlock(); } } }

     总结:使用Synchronized和Lock都能实现,而Lock的优势是可以精准唤醒,不像Synchronized的只能notifyAll()

     
  • 相关阅读:
    当一组单选按钮中的一个选中,后文本框为只读属性
    在.net 环境下,进行了伪静态页面处理后,后台的Fckeditor就不能正常显示了
    PL/SQL Developer 8注册码
    选中checkbox后才能填写输入框
    net 试图加载格式不正确的程序。(Exception from HRESULT: 0x8007000B)
    在sql中将varchar型转换成int型再进行排序
    ASP.NET中显示农历时间
    改变自己,拥抱生活
    人生最不值得你去做的事情
    Oracle 中的周、月、日历的查询实现
  • 原文地址:https://www.cnblogs.com/yayin/p/14193850.html
Copyright © 2020-2023  润新知