zoukankan      html  css  js  c++  java
  • 奇偶数线程交替执行问题

    一个面试题:两个线程,一个打印偶数,一个打印奇数,并且轮流打印,我们可以看到这种场景模式肯定是需要通过同步来实现,

    实现通过的方式我们可以采用ReentrantLock来实现,也可以通过采用synchronized来实现,下边就这两种方式进行

    实现,平时感觉自己代码还是敲的少,以后还是要加强代码量;

    方式一:通过synchronized来实现,使用该种方式实现,有两个要点记录,一个是:我们在没有使用锁对象的wait()

    方法时,调用其notify()没有影响,所以比如一段代码,上来就针对一个对象锁进行notify()是没有问题的;

    两一个是:在对象锁的wait方法被唤醒后,在wait的地方继续执行,同时执行完代码块后优先拿到该对象锁,进入其wait状态;

    这样技术num使用 AtomicInteger;

    偶数线程:

       private Object obj;
        private AtomicInteger  num;
        EventThread()
        {
        }
        EventThread(Object obj, AtomicInteger  num)
        {
            this.obj = obj;
            this.num = num;
        }
        @Override
        public void run()
        { 
            while(num.get()<100)
            {
                synchronized(obj)
                {
                    System.out.println("双线程wait前....");
                    while(num.get() % 2 != 0)
                    {
                        try{
                            obj.wait();
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    } 
                    System.out.println(Thread.currentThread() + ": " + num);
                    System.out.println("双线程wait后....");
                    this.num.getAndIncrement();
                    obj.notify();
                }
            }    
        }

    奇数线程:

        private Object obj = null;
        private AtomicInteger num;
        private boolean flag = false;
    
        OddThread()
        {
        }
        OddThread(Object obj, AtomicInteger num)
        {
            this.obj = obj;
            this.num = num;
        }
        @Override
        public void run()
        {
            while(num.get() < 100)
            {
                synchronized(obj)
                {    
                    System.out.println("单线程wait前....");
                    while(num.get()%2 == 0)
                    {
                        try {
                            obj.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    
                    System.out.println(Thread.currentThread() + ": " + num);
                    System.out.println("单线程wait后....");
                    this.num.getAndIncrement();
                    obj.notify();
                    
                }
            }    
        }

    main函数:

         AtomicInteger ai = new AtomicInteger(1);
            Object obj = new Object();
                    
            OddThread ot = new OddThread(obj, ai);
            EventThread et = new EventThread(obj, ai);
            
            Thread odd = new Thread(ot);
            odd.setName("单数线程");
            Thread event = new Thread(et);
            event.setName("双数线程");
            odd.setPriority(10);
            odd.start();
            event.start();

    方式二:使用ReentantLock实现;

    道理是一样的;

    奇数线程:

    private Lock lock;
        private Condition odd;
        private Condition event;
        int num = 0;
    
        OddThread()
        {
        }
        OddThread(Lock lock, Condition odd, Condition event, int num)
        {
            this.lock = lock;
            this.event = event;
            this.odd = odd;
            this.num = num;
        }
        
        @Override
        public void run()
        {
            
            for(num=1; num<=100; num+=2)
            {
                lock.lock();
                System.out.println("wait前代码执行。。。. ");
                System.out.println(Thread.currentThread() + ": " + num);
                
                try {
                    odd.await();
                    event.signal();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("wait后代码执行。。。。 ");
                lock.unlock();
            }    
        }

    偶数线程:

    private Lock lock;
        private Condition odd;
        private Condition event;
        int num = 0;
        EventThread()
        {
        }
        EventThread(Lock lock, Condition odd, Condition event, int num)
        {
            this.lock = lock;
            this.event = event;
            this.odd = odd;
            this.num = num;
        }
        @Override
        public void run()
        { 
            for(num=2; num<=100; num+=2)
            {
                lock.lock();
                System.out.println(Thread.currentThread() + ": " + num);
                try {
                    odd.signal();
                    event.await();
                } catch (Exception e) {
                    e.printStackTrace();
                }    
                lock.unlock();
            }    
        }

    main函数:

            int num = 1;
            Lock lock = new ReentrantLock();
            Condition o = lock.newCondition();
            Condition e = lock.newCondition();
            OddThread ot = new OddThread(lock, o, e, num);
            EventThread et = new EventThread(lock, o, e, num);
            Thread odd = new Thread(ot);
            odd.setName("单数线程");
            Thread event = new Thread(et);
            event.setName("双数线程");
            odd.setPriority(10);
            odd.start();
            event.start();
  • 相关阅读:
    SQL的update from 理解
    JS自动合并表格
    完全备份ORACLE数据库 并在另一台电脑上恢复
    cmd 连接到指定路径
    oracle 11g 64位安装sqldeveloper打开不了
    oracle 11g卸载方法
    sql的游标使用(转)
    JQEUERY案例
    sessionStorage实现note的功能
    Web Worker模拟抢票
  • 原文地址:https://www.cnblogs.com/gxyandwmm/p/9675489.html
Copyright © 2011-2022 走看看