• [CareerCup] 16.5 Semphore 信号旗


    16.5 Suppose we have the following code:
    public class Foo {
      public Foo() { . . . }
      public void first() { ... }
      public void second() { ... }
      public void thirdQ { ... }
    }
    The same instance of Foo will be passed to three different threads. ThreadA will call first, threads will call second, and threadC will call third. Design a mechanism to ensure that first is called before second and second is called before third.

    按照题目中要求的顺序即需满足在执行second()前检测first()是否完成了,在执行third()前检测second()是否完成了,由于我们需要考虑线程安全,所以布尔型的标记不行,那么使用锁呢,看如下代码:

    import java.util.concurrent.locks.ReentrantLock;
    
    public class FooBad {
        public int pauseTime = 10000;
        public ReentrantLock lock1;
        public ReentrantLock lock2;
        
        public FooBad() {
            try {
                lock1 = new ReentrantLock();
                lock2 = new ReentrantLock();
                lock1.lock();
                lock2.lock();
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
        
        public void first() {
            try {
                System.out.println("Started Executing 1");
                Thread.sleep(pauseTime);
                System.out.println("Finished Executing 1");
                lock1.unlock();
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
        
        public void second () {
            try {
                lock1.lock();
                lock1.unlock();
                System.out.println("Started Executing 2");
                Thread.sleep(pauseTime);
                System.out.println("Finished Executing 2");
                lock2.unlock();
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
        
        public void third() {
            try {
                lock2.lock();
                lock2.unlock();
                System.out.println("Started Executing 3");
                Thread.sleep(pauseTime);
                System.out.println("Finished Executing 3");
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
    }
    
    public class MyThread extends Thread {
        private String method;
        private FooBad foo;
        
        public MyThread(FooBad foo, String method) {
            this.method = method;
            this.foo = foo;
        }
        
        public void run() {
            if (method == "first") {
                foo.first();
            } else if (method == "second") {
                foo.second();
            } else if (method == "third") {
                foo.third();
            }
        }
    }
    
    public class j {
        public static void main(String[] args) {
            FooBad foo = new FooBad();
            
            MyThread thread1 = new MyThread(foo, "first");
            MyThread thread2 = new MyThread(foo, "second");
            MyThread thread3 = new MyThread(foo, "third");
            
            thread3.start();
            thread2.start();
            thread1.start();
        }
    }

    上述代码并不能很好的完成题目中要求的顺序,因为锁的所有权的问题。一个线程操作一个锁,当别的线程是无法解这个线程的锁的,所以用锁是不行的。我们可以使用信号旗Semaphores,参见代码如下:

    import java.util.concurrent.Semaphore;
    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReentrantLock;
    
    public class Foo {
        public int pauseTime = 1000;
        public Semaphore sem1;
        public Semaphore sem2;
        
        public Foo() {
            try {
                sem1 = new Semaphore(1);
                sem2 = new Semaphore(1);
                sem1.acquire();
                sem2.acquire();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        
        public void first() {
            try {
                System.out.println("Started Executing 1");
                Thread.sleep(pauseTime);
                System.out.println("Finished Executing");
                sem1.release();
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
        
        public void second() {
            try {
                sem1.acquire();
                sem1.release();
                System.out.println("Started Executing 2");
                Thread.sleep(pauseTime);
                System.out.println("Finished Executing 2");
                sem2.release();
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
        
        public void third() {
            try {
                sem2.acquire();
                sem2.release();
                System.out.println("Started Executing 3");
                Thread.sleep(pauseTime);
                System.out.println("Finished Executing 3");
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
    }
    
    public class MyThread extends Thread {
        private String method;
        private Foo foo;
        
        public MyThread(Foo foo, String method) {
            this.method = method;
            this.foo = foo;
        }
        
        public void run() {
            if (method == "first") {
                foo.first();
            } else if (method == "second") {
                foo.second();
            } else if (method == "third") {
                foo.third();
            }
        }
    }
    
    public class j {
        public static void main(String[] args) {
            Foo foo = new Foo();
            
            MyThread thread1 = new MyThread(foo, "first");
            MyThread thread2 = new MyThread(foo, "second");
            MyThread thread3 = new MyThread(foo, "third");
            
            thread3.start();
            thread2.start();
            thread1.start();
        }
    }

    CareerCup All in One 题目汇总

  • 相关阅读:
    【HDOJ6667】Roundgod and Milk Tea(模拟)
    【HDOJ6655】Just Repeat(贪心)
    【HDOJ6651】Final Exam(贪心)
    【HDOJ6646】A + B = C(模拟)
    【HDOJ6656】Kejin Player(期望DP)
    【2019 Multi-University Training Contest 7】
    【HDOJ6635】Nonsense Time(时间倒流,lis)
    【HDOJ6638】Snowy Smile(线段树)
    【HDOJ6641】TDL(数论)
    【HDOJ6645】Stay Real(堆)
  • 原文地址:https://www.cnblogs.com/grandyang/p/5400632.html
Copyright © 2020-2023  润新知