• LeetCode1114.按序打印 Java实现及测试方法


    原题:

    我们提供了一个类:

    public class Foo {
      public void first() { print("first"); }
      public void second() { print("second"); }
      public void third() { print("third"); }
    }
    三个不同的线程将会共用一个 Foo 实例。

    线程 A 将会调用 first() 方法
    线程 B 将会调用 second() 方法
    线程 C 将会调用 third() 方法

    分析:目的是实现三个线程间的运行顺序控制,使用一个共享voaltile变量或者使用AtomicInteger都可以作为一个flag,各个线程通过这个flag来调度。这样各个线程中只有set和get操作,没有getAndOperate操作,个人认为没有必要加锁,用volatile变量在这正合适(volatile不保证原子性,不要用在i++等非原子操作上)。

    代码如下,第一次在leetcode做多线程题纠结了好一会测试方法咋写,还是太菜了。。

    static class Foo {
            private volatile int flag = 0;
    
            public Foo() {
    
            }
    
            public void first(Runnable printFirst) throws InterruptedException {
    
                // printFirst.run() outputs "first". Do not change or remove this line.
                printFirst.run();
                flag = 1;
            }
    
            public void second(Runnable printSecond) throws InterruptedException {
                while (flag!=1){
                }
                // printSecond.run() outputs "second". Do not change or remove this line.
                printSecond.run();
                flag = 2;
            }
    
            public void third(Runnable printThird) throws InterruptedException {
                while (flag!=2){
                }
                // printThird.run() outputs "third". Do not change or remove this line.
                printThird.run();
            }
    
        }
        //使用原子变量实现
    //    static class Foo {
    //        private AtomicInteger flag = new AtomicInteger(0);
    //
    //        public Foo() {
    //
    //        }
    //
    //        public void first(Runnable printFirst) throws InterruptedException {
    //
    //            // printFirst.run() outputs "first". Do not change or remove this line.
    //            printFirst.run();
    //            flag.set(1);
    //        }
    //
    //        public void second(Runnable printSecond) throws InterruptedException {
    //            while (flag.get() !=1){
    //            }
    //            // printSecond.run() outputs "second". Do not change or remove this line.
    //            printSecond.run();
    //            flag.set(2);
    //        }
    //
    //        public void third(Runnable printThird) throws InterruptedException {
    //            while (flag.get() !=2){
    //            }
    //            // printThird.run() outputs "third". Do not change or remove this line.
    //            printThird.run();
    //        }
    //
    //    }
    
        public static void main(String[] args) throws InterruptedException {
            Foo foo = new Foo();
            ExecutorService executorService = Executors.newFixedThreadPool(5);
            //匿名内部类写法
            executorService.submit(new Runnable() {
                @Override
                public void run() {
                    try {
                        foo.first(new Runnable() {
                            @Override
                            public void run() {
                                System.out.print("first");
                            }
                        });
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            });
            //lambda表达式写法
            executorService.submit(() -> {
                try {
                    foo.second(() -> System.out.print("second"));
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });
            executorService.submit(()->{
                try {
                    foo.third(()->System.out.print("third"));
                }catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });
        }

    从AtomicInteger和volatile变量运行结果看,时间、消耗都相同,因为这里只用到了AtomicInteger的get和set方法,没有用到需要CAS的操作(当然这就是使用volatile的原因,如果有需要cas的操作那就不能用了),和直接用volatile变量其实是完全相同的。

  • 相关阅读:
    Oracle 11g db_ultra_safe参数
    How To Configure NTP On Windows 2008 R2 (zt)
    Brocade光纤交换机密码重置 (ZT)
    perl如何访问Oracle (ZT)
    Nagios check_nrpe : Socket timeout after 10 seconds
    oracle10g单机使用ASM存储数据
    Xmanager无法连接Solaris10 (ZT)
    Solaris10配置iscsi initiator
    oracle 11g dataguard 创建过程
    Nagios check_procs pst3 报错
  • 原文地址:https://www.cnblogs.com/pauljoyce/p/13646181.html
Copyright © 2020-2023  润新知