当前位置 主页 > 网站技术 > 代码类 >

    Java 信号量Semaphore的实现

    栏目:代码类 时间:2019-09-12 11:14

    近日于LeetCode看题遇1114 按序打印,获悉一解法使用了Semaphore,顺势研究,记心得于此。

    此解视Semaphore为锁,以保证同一时刻单线程的顺序执行。在此原题上,我作出如下更改。

    package test; import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.Semaphore; public class SemaphoreDemo { static Semaphore A; static Semaphore B; static Semaphore C;  public static void main(String[] args) throws InterruptedException {     A = new Semaphore(1);    B = new Semaphore(0);    C = new Semaphore(0);        ExecutorService ex=Executors.newFixedThreadPool(10);     for (int i = 0; i <7; i++) {  ex.execute(new R1());  ex.execute(new R2());  ex.execute(new R3()); }    ex.shutdown();  }     public static class R1 implements Runnable{ @Override public void run() {  try {//  A.acquire();  System.out.println("1"+Thread.currentThread().getName());//  B.release();  } catch (Exception e) {  e.printStackTrace();  } }   }  public static class R2 implements Runnable{ @Override public void run() {  try {//  B.acquire();  System.out.println("2"+Thread.currentThread().getName());//  C.release();  } catch (Exception e) {  e.printStackTrace();  } }   }  public static class R3 implements Runnable{ @Override public void run() {  try {//  C.acquire();  System.out.println("3"+Thread.currentThread().getName());//  A.release();  } catch (Exception e) {  e.printStackTrace();  } }   } }

    10个线程的常量池中,分别调用R1,R2,R3的方法多次,控制台输出对应各方法名拼接执行该方法的线程名。多次执行结果各不相同:

    1pool-1-thread-12pool-1-thread-21pool-1-thread-43pool-1-thread-62pool-1-thread-53pool-1-thread-31pool-1-thread-72pool-1-thread-83pool-1-thread-93pool-1-thread-12pool-1-thread-81pool-1-thread-43pool-1-thread-11pool-1-thread-22pool-1-thread-91pool-1-thread-103pool-1-thread-12pool-1-thread-51pool-1-thread-63pool-1-thread-42pool-1-thread-8
    1pool-1-thread-12pool-1-thread-23pool-1-thread-31pool-1-thread-42pool-1-thread-53pool-1-thread-61pool-1-thread-72pool-1-thread-83pool-1-thread-91pool-1-thread-103pool-1-thread-11pool-1-thread-42pool-1-thread-83pool-1-thread-32pool-1-thread-101pool-1-thread-22pool-1-thread-93pool-1-thread-41pool-1-thread-73pool-1-thread-62pool-1-thread-5

    方法能调用,多线程下却无法保证方法的顺序执行。使用Semaphore后,代码为:

    package test; import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.Semaphore; public class SemaphoreDemo { static Semaphore A; static Semaphore B; static Semaphore C;  public static void main(String[] args) throws InterruptedException {     A = new Semaphore(1);    B = new Semaphore(0);    C = new Semaphore(0);        ExecutorService ex=Executors.newFixedThreadPool(10);     for (int i = 0; i <7; i++) {  ex.execute(new R1());  ex.execute(new R2());  ex.execute(new R3()); }    ex.shutdown();  }     public static class R1 implements Runnable{ @Override public void run() {  try {  A.acquire();  System.out.println("1"+Thread.currentThread().getName());  B.release();  } catch (Exception e) {  e.printStackTrace();  } }   }  public static class R2 implements Runnable{ @Override public void run() {  try {  B.acquire();  System.out.println("2"+Thread.currentThread().getName());  C.release();  } catch (Exception e) {  e.printStackTrace();  } }   }  public static class R3 implements Runnable{ @Override public void run() {  try {  C.acquire();  System.out.println("3"+Thread.currentThread().getName());  A.release();  } catch (Exception e) {  e.printStackTrace();  } }   } }