zoukankan      html  css  js  c++  java
  • 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变量其实是完全相同的。

  • 相关阅读:
    rename 批量重命名
    shell脚本实现轮询查看进程是否结束
    mysql 修改max_connections
    window10下的solr6.1.0入门笔记之---安装部署
    php下载大文件
    【转】Pyhton 单行、多行注释符号使用方法及规范
    window10系统下使用python版本实现mysql查询
    Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A
    【Visual Studio】 使用EF、 Linq2Sql快速创建数据交互层(一)
    【OPCAutomation】 使用OPCAutomation实现对OPC数据的访问
  • 原文地址:https://www.cnblogs.com/pauljoyce/p/13646181.html
Copyright © 2011-2022 走看看