关于Java 信号量 Semaphore

2023年1月2日08:29:36

今天看面试题碰到这么一题:有三个线程ID分别是A、B、C,请有多线编程实现,在屏幕上循环打印10次ABCABC...

具体答案先贴出来:

package com.joey.threadLocal;
import java.util.concurrent.Semaphore;

public class PrintABC {
	 
	    private static Semaphore semaphore1 = new Semaphore(0);
	    private static Semaphore semaphore2 = new Semaphore(0);
	    private static Semaphore semaphore3 = new Semaphore(0);
	    public Thread t1;
	    public Thread t2;
	    public Thread t3;
	 
	    int count = 10;
	     
	    public PrintABC() {
	        t1 = new Thread() {
	            public void run() {
	                try {
	                    semaphore3.release();
	                    int i = 0;
	                    while(i++ < count) {
	                        semaphore3.acquire();
	                        System.out.print("A");
	                        semaphore1.release();
	                    }
	                } catch (Exception e) {
	                    e.printStackTrace();
	                }
	            }
	        };
	        t2 = new Thread() {
	            public void run() {
	                try {
	                    int i = 0;
	                    while(i++ < count) {
	                        semaphore1.acquire();
	                        System.out.print("B");
	                        semaphore2.release();
	                    }
	                } catch (InterruptedException e) {
	                    e.printStackTrace();
	                }
	            }
	        };
	        t3 = new Thread() {
	            public void run() {
	                try {
	                    int i = 0;
	                    while(i++ < count) {
	                        semaphore2.acquire();
	                        System.out.print("C");
	                        semaphore3.release();
	                    }
	                } catch (InterruptedException e) {
	                    e.printStackTrace();
	                }
	            }
	        };
	 
	    }
	 
	    public void run() {
	        t1.start();
	        t2.start();
	        t3.start();
	    }
	 
	    public static void main(String args[]) throws Exception {
	    	PrintABC t = new PrintABC();
	        t.run();
	    }
	}



这里面用到了java信号量Semaphore,首先讲一下
概念 :Semaphore当前在多线程环境下被扩放使用,操作系统的信号量是个很重要的概念,在进程控制方面都有应用。Java 并发库 的Semaphore 可以很轻松完成信号量控制,Semaphore可以控制某个资源可被同时访问的个数,通过 acquire() 获取一个许可,如果没有就等待,而 release() 释放一个许可。比如在Windows下可以设置共享文件的最大客户端访问个数。

那么我们看到,在上面的例子中创建了三个new Semaphore(0)示例,且创建时的传递到传递的参数为0,表示此时如果对象调用acquire()方法则获取不到许可,测试调用所在的线程将处于等待状态,只到有新的许可被释放。根绝这个逻辑就很容易理解上面的代码了,首先刚开始的时候t1,t2,t3三个线程只有t1不用等待,因为t2,t3两个线程的run()方法中首先对semaphore1和semaphore2申请一个许可,但此时这两个信号量示例的许可群为0,但是对于t1线程,它提前调用了semaphore3的release()方法,使semaphore3之后调用acquire()方法去获取并消费一个许可时可以得到许可,之后semaphore1调用release()释放一个许可时下面的t2线程可以终止等待继续往下执行,以此类推.....

而且通过实验可以发现,每次调用一次release()会增加一个许可,比如


final Semaphore semp = new Semaphore(5);
的效果与
final Semaphore semp1 = new Semaphore(<span style="font-family:微软雅黑, 'MS Sans Serif', sans-serif;">0</span>);
semp1.release();
semp1.release();
semp1.release();
semp1.release();
semp1.release();
的许可数应该是一样的

初次接触,就这点了解,以后遇到了再深究

  • 作者:王召宇
  • 原文链接:https://blog.csdn.net/IOpfan/article/details/51282424
    更新时间:2023年1月2日08:29:36 ,共 1923 字。