zoukankan      html  css  js  c++  java
  • 斐讯面试记录—三线程交替打印ABC

    package cn.shenzhen.feixun;
    
    public class PrintABC extends Thread{
        private String name;
        private Object prev;
        private Object self;
        
        
        public PrintABC(String name,Object prev,Object self){
            this.name=name;
            this.prev=prev;
            this.self=self;
        }
        /**
         * ,为了控制执行的顺序,必须要先持有prev锁,
         * 也就是前一个线程要释放自身对象锁,再去申请自身对象锁,两者兼备时打印字母,
         * 之后首先调用self.notify()释放自身对象锁,唤醒下一个等待线程,
         * 再调用prev.wait()释放prev对象锁,终止当前线程,等待循环结束后再次被唤醒。
         * 程序运行的主要过程就是A线程最先运行,持有C,A对象锁,后释放A,C锁,唤醒B。
         * 线程B等待A锁,再申请B锁,后打印B,再释放B,A锁,唤醒C,线程C等待B锁,再申请C锁,
         * 后打印C,再释放C,B锁,唤醒A……
         */
        public void run(){
            int count=0;
            while(count<10){
                // 先获取 prev锁 如此问题中先将对象C锁住
                synchronized (prev) {
                    //然后获取自身的锁如此问题中将对象A锁住
                    synchronized (self) {
                        System.out.print(name+"");
                        count++;
                        self.notify();//此问题中一共有三个对象ABC此时将self唤醒,是其他线程来竞争self
                    }
                    try {
                        prev.wait();
                        /**
                         * 注意的是notify()调用后,并不是马上就释放对象锁,
                         * 而是在相应的synchronized(){}语句块执行结束,自动释放锁,
                         * JVM会在wait()对象锁的线程中随机选取一线程,赋予其对象锁,唤醒线程,继续执行。 
                         */
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
        public static void main(String[] args) throws InterruptedException {
            Object a=new Object();
            Object b=new Object();
            Object c=new Object();
            
            PrintABC printA=new PrintABC("A", c, a);//第一个线程先将AC对象锁住,A执行完了之后释放锁
            PrintABC printB=new PrintABC("B", a, b);
            PrintABC printC=new PrintABC("C", b, c);
            
            /**
             * 为了避免JVM启动ThreadA、ThreadB、ThreadC三个线程顺序的不确定性。
             * 需要让A,B,C三个线程以确定的顺序启动,中间加一段sleep确保前一个线程已启动。
             */
            printA.start();
            /**
             * sleep()方法导致了当前线程暂停执行指定的时间,
             * 让出cpu该其他线程,但是他的监控状态依然保持者,
             * 当指定的时间到了又会自动恢复运行状态。
             */
            printA.sleep(10);
            printB.start();
            printB.sleep(10);
            printC.start();
            printC.sleep(10);
        }
    }
  • 相关阅读:
    如何在delphi里面控制Edit只能输入数字
    ShellExecute函数
    GetSystemMenu 获取系统菜单
    StringReplace 函数
    delphi 字符串查找
    Pos 函数
    Copy 函数
    css笔记
    HTML5笔记
    node.js nodejs supvisor模块
  • 原文地址:https://www.cnblogs.com/lingyejun/p/7159230.html
Copyright © 2011-2022 走看看