From e4643b907fbf394a0cfbdc7b093949d2a04bb436 Mon Sep 17 00:00:00 2001 From: Hui Date: Sun, 10 May 2020 00:08:05 +0800 Subject: [PATCH] =?UTF-8?q?=E8=A1=A5=E5=85=85=E4=BD=BF=E7=94=A8Semaphore?= =?UTF-8?q?=E7=9A=84=E6=96=B9=E5=BC=8F=EF=BC=8C=E4=B8=8D=E8=BF=87=E6=98=AF?= =?UTF-8?q?Semaphore=E6=AF=94=E8=BE=83=E5=81=8F=E9=97=A8=E7=9A=84=E7=94=A8?= =?UTF-8?q?=E6=B3=95=EF=BC=8C=E4=BA=8B=E5=AE=9E=E4=B8=8A=E4=B9=9F=E6=B2=A1?= =?UTF-8?q?=E4=BB=80=E4=B9=88=E6=96=B0=E6=84=8F=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../A1B2C3/Print1A2B3C_Semaphore.java | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 src/main/java/com/mashibing/juc/c_026_00_interview/A1B2C3/Print1A2B3C_Semaphore.java diff --git a/src/main/java/com/mashibing/juc/c_026_00_interview/A1B2C3/Print1A2B3C_Semaphore.java b/src/main/java/com/mashibing/juc/c_026_00_interview/A1B2C3/Print1A2B3C_Semaphore.java new file mode 100644 index 0000000..4f84f65 --- /dev/null +++ b/src/main/java/com/mashibing/juc/c_026_00_interview/A1B2C3/Print1A2B3C_Semaphore.java @@ -0,0 +1,52 @@ +package com.mashibing.juc.c_026_00_interview.A1B2C3; + +import java.util.concurrent.Semaphore; + +/** + * 使用Semaphore的方式,它本质上也是用了“许可”的概念。跟使用LockSupport、BlockingQueue完成此功能是相似的。 + * 通常来说Semaphore的用法是:多个线程执行一个被同一个semaphore的 semaphore.acquire()和 semaphore.release() 包围的一段代码以控制同时执行这段代码的线程数量【哪个线程acquire了semaphore的许可,哪个线程就release许可】 + * 但现在是一个线程中多次执行semaphore.acquire() 导致该semaphore许可用尽而阻塞,然后等待其他的线程中进行该semaphore.release()许可回收。 + */ +public class Print1A2B3C_Semaphore { + + public static void main(String[] args) { + //创建两个Semaphore用于线程间通信 + Semaphore s1 = new Semaphore(1); + Semaphore s2 = new Semaphore(1); + + //t1线程输出的数字 + char[] aI = "1234567".toCharArray(); + + //t2线程输出的字母 + char[] aC = "ABCDEFG".toCharArray(); + + + Thread t1 = new Thread(() -> { + for(char c : aI) { + //t1 直接进入循环,先s1.acquire(),第一次循环时不会阻塞 + try { s1.acquire(); } catch (Exception e) {} + + System.out.print(c); + //t1 输出一个元素后,释放s2,让t2执行 + try { s2.release(); } catch (Exception e) {} + } + }); + + Thread t2 = new Thread(() -> { + //因为控制t1先输出,所以t2要控制住一开始不能输出,循环执行先s2.acquire(),注意此时不会阻塞 + try { s2.acquire(); } catch (Exception e) {} + + //然后进入循环 + for(char c : aC) { + try { s2.acquire(); } catch (Exception e) {} + System.out.print(c + " "); + try { s1.release(); } catch (Exception e) {} + } + }); + + //启动两个线程 + t1.start(); + t2.start(); + } + +}