记一道多线程题目(二)

记训练营给师弟的第二道多线程训练

一、题目与要求

/**
 * @author linxu
 * @date 2019
 * tips:
 * 1、交替打印,根据构造器构造的N,构造一个交替任务执行器。
 * 2、假如N=1,则打印12,假如N=2.则打印1212。
 * 3、效率第一,可有多种解法,适当加分。
 */  
static class PrintOrdered {
        private int n;

        public PrintOrdered(int n) {
            this.n = n;
        }

        public void one() throws InterruptedException {
          //这部分内容可以修改
            for (int i = 0; i < n; i++) {
                System.out.print("1");
            }
        }

        public void two() throws InterruptedException {
          //这部分内容可以修改
            for (int i = 0; i < n; i++) {
                System.out.print("2");
            }
        }
    }
	//main方法内容不允许修改
    public static void main(String[] args) throws InterruptedException{
     
        PrintOrdered printOrdered=new PrintOrdered(100);
        Runnable r1 = () -> {
            try {
                printOrdered.one();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        };
        Runnable r2 = () -> {
            try {
                printOrdered.two();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        };
        Thread t=new Thread(r1);
        Thread t1=new Thread(r2);
        //keep sync
        Thread.sleep(100);
        //start
        t.start();
        t1.start();
    }

二、解法一

//使用自旋解法,可以采用volatile加速自旋解锁速度。
static class PrintOrdered {
        private int n;
   		private /*volatile*/ boolean flag;

        public PrintOrdered(int n) {
            this.n = n;
   			this.flag=true;
        }

        public void one() throws InterruptedException {
            for (int i = 0; i < n; i++) {
              while(flag!=true){
                //空自旋
              }
                System.out.print("1");
                flag=false;
            }
        }

        public void two() throws InterruptedException {
            for (int i = 0; i < n; i++) {
              while(flag!=false){
                //空自旋
              }
                System.out.print("2");
                flag=true;
            }
        }
    }

三、解法二

//使用阻塞队列解法。
static class PrintOrdered {
        private int n;
        private BlockingQueue<Integer> oneQueue;
        private BlockingQueue<Integer> twoQueue;

        public PrintOrdered(int n) {
            this.n = n;
            twoQueue = new LinkedBlockingQueue<>();
            ArrayList<Integer> arrayList = new ArrayList();
            arrayList.add(0);
            oneQueue = new LinkedBlockingQueue<>(arrayList);
        }

        public void one() throws InterruptedException {
            for (int i = 0; i < n; i++) {
                oneQueue.take();
                System.out.print("1");
                twoQueue.put(i);
            }
        }

        public void two() throws InterruptedException {
            for (int i = 0; i < n; i++) {
                twoQueue.take();
                System.out.print("2");
                oneQueue.put(i);
            }
        }
    }

四、解法三

//重入锁解法  
static class PrintOrdered {
        private int n;
        private ReentrantLock lock = new ReentrantLock();
        private Condition condition1 = lock.newCondition();
        private Condition condition2 = lock.newCondition();
        private int flag=0;

        public PrintOrdered(int n) {
            this.n = n;
        }

        public void one() throws InterruptedException {
            for (int i = 0; i < n; i++) {
                // oneQueue.take();
                lock.lock();
                try {
                    if (flag!=0){
                        condition1.await();
                    }
                    System.out.print("1");
                    flag++;
                    condition2.signal();
                } finally {
                    lock.unlock();
                }
                // twoQueue.put(i);
            }
        }

        public void two() throws InterruptedException {
            for (int i = 0; i < n; i++) {
                //  twoQueue.take();
                lock.lock();
                try {
                    if (flag!=1){
                        condition2.await();
                    }
                    System.out.print("2");
                    flag--;
                    condition1.signal();
                } finally {
                    lock.unlock();
                }
                // oneQueue.put(i);
            }
        }
    }

    public static void main(String[] args) throws InterruptedException{
        PrintOrdered printOrdered=new PrintOrdered(100);
        Runnable r1 = () -> {
            try {
                printOrdered.one();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        };
        Runnable r2 = () -> {
            try {
                printOrdered.two();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        };
        Thread t=new Thread(r1);
        Thread t1=new Thread(r2);
        //keep sync
        Thread.sleep(100);
        //start
        t.start();
        t1.start();
    }
发布了57 篇原创文章 · 获赞 32 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/rekingman/article/details/97491056