首页 > 编程语言 >java线程之Semaphore

java线程之Semaphore

时间:2023-04-26 20:02:34浏览次数:38  
标签:java 乘客 import 离开 线程 Semaphore 坐下 座位 TOTAL


Semaphore是信号量,用于线程间同步。

例子,公交车上大概有24个座位,但是车上总共有40个人,那么,只要有一个人下车,另一个人就能得到一个座位,假设到终点站之前,每个人都能坐下。

代码如下:

package com.concurrent;

import java.util.Random;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;

import junit.framework.TestCase;

public class TestSemaphore extends TestCase {
	private static final int TOTAL_SEAT = 26;

	private static final int TOTAL_PASSENGER = 40;

	public void testSemaphore() {
		ExecutorService executorService = Executors.newFixedThreadPool(TOTAL_PASSENGER);
		final Semaphore semaphore = new Semaphore(TOTAL_SEAT);
		final CountDownLatch cdl = new CountDownLatch(TOTAL_PASSENGER);
		final Random random = new Random();

		for (int i = 0; i < TOTAL_PASSENGER; i++) {
			final int index = i + 1;
			Runnable r = new Runnable() {

				@Override
				public void run() {
					try {
						semaphore.acquire();
						System.out.println("乘客" + index + " 坐下");
						Thread.sleep(random.nextInt(10) * 1000);
					} catch (InterruptedException e) {
						e.printStackTrace();
					} finally {
						System.out.println("乘客" + index + " 离开座位");
						semaphore.release();
						cdl.countDown();
					}
				}
			};
			executorService.submit(r);
		}
		executorService.shutdown();

		try {
			cdl.await();
			System.out.println("到终点站了");
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
}



输出:

乘客2 坐下
乘客1 坐下
乘客3 坐下
乘客5 坐下
乘客4 坐下
乘客7 坐下
乘客6 坐下
乘客8 坐下
乘客10 坐下
乘客11 坐下
乘客9 坐下
乘客11 离开座位
乘客13 坐下
乘客12 坐下
乘客17 坐下
乘客14 坐下
乘客15 坐下
乘客16 坐下
乘客18 坐下
乘客19 坐下
乘客20 坐下
乘客21 坐下
乘客22 坐下
乘客24 坐下
乘客23 坐下
乘客27 坐下
乘客26 坐下
乘客25 坐下
乘客10 离开座位
乘客8 离开座位
乘客28 坐下
乘客31 坐下
乘客14 离开座位
乘客29 坐下
乘客21 离开座位
乘客12 离开座位
乘客23 离开座位
乘客33 坐下
乘客32 坐下
乘客30 坐下
乘客33 离开座位
乘客34 坐下
乘客34 离开座位
乘客35 坐下
乘客7 离开座位
乘客36 坐下
乘客26 离开座位
乘客37 坐下
乘客17 离开座位
乘客38 坐下
乘客20 离开座位
乘客39 坐下
乘客6 离开座位
乘客40 坐下
乘客30 离开座位
乘客37 离开座位
乘客4 离开座位
乘客40 离开座位
乘客18 离开座位
乘客19 离开座位
乘客16 离开座位
乘客25 离开座位
乘客35 离开座位
乘客29 离开座位
乘客2 离开座位
乘客13 离开座位
乘客39 离开座位
乘客22 离开座位
乘客36 离开座位
乘客3 离开座位
乘客28 离开座位
乘客15 离开座位
乘客24 离开座位
乘客32 离开座位
乘客1 离开座位
乘客5 离开座位
乘客9 离开座位
乘客27 离开座位
乘客31 离开座位
乘客38 离开座位
到终点站了




标签:java,乘客,import,离开,线程,Semaphore,坐下,座位,TOTAL
From: https://blog.51cto.com/u_1002776/6228780

相关文章

  • java线程之FutureTask
    FutureTask是线程的异步计算。如果有多个线程,每个线程都要花很多时间计算,而且所花时间不同,最后要统计,就要用到此类。此类有个done方法,等call完后,执行此方法。代码:packagecom.concurrent;importjava.util.ArrayList;importjava.util.List;importjava.util.Random;importja......
  • java线程之wait、notifyAll
    wait、notifyAll是线程之间用来通信的,设计模式里的观察者模式。例子,上课前,同学在玩,一个同学观察老师是不是来了,如果来了,叫其他同学坐好。packagecom.concurrent;importjava.util.HashSet;importjava.util.Set;importjava.util.concurrent.CountDownLatch;importjava.util......
  • java之用volatile和不用volatile的区别
    在当前的Java内存模型下,线程可以把变量保存在本地内存(比如机器的寄存器)中,而不是直接在主存中进行读写。这就可能造成一个线程在主存中修改了一个变量的值,而另外一个线程还继续使用它在寄存器中的变量值的拷贝,造成数据的不一致。 要解决这个问题,只需要像在本程序中的这样,把该变量......
  • java流程控制
    scanner创建一个新的扫描器对象,用于接受键盘数据Scannerscanner=newScanner(System.in);//使用next方式接收Stringsrt=scanner.next();//使用nextLine方式接收Stringsrt=scanner.nextLine();next():一定要读取到有效字符后才可以结束输入对输入有效字符之前......
  • 深入java虚拟机 - 垃圾收集 - 引用计数收集器
         引用计数是垃圾收集的早期策略。在这种方法中,堆中每一个对象都有一个引用计数。一个对象被创建了,并且指向该对象的引用被分配给一个变量,这个对象的引用计数被置为1。当任何其他变量被赋值为对这个对象的引用时,计数加1。当一个对象的引用超过了......
  • java 多线程 synchronized
    程序1:packagetestsynchronized;publicclassThread1implementsRunnable{ @Override publicvoidrun(){ synchronized(this){ for(inti=0;i<10;i++){ System.out.println(Thread.currentThread().getName() +"synchronizedloo......
  • java 一些奇怪的笔试题
    例1:packagecom.test;publicclassTest1{ publicvoidtestExit(){ try{ System.exit(0); }finally{ System.out.println("testExit"); } } publicvoidtestReturn(){ try{ return; }finally{ System.out.println("......
  • docker启动rabbitMQ,通过java创建交换机、队列、绑定
    通过docker启动rabbitMQdockerrun-d--namerabbitmq-p5671:5671-p5672:5672-p4369:4369-p25672:25672-p15671:15671-p15672:15672rabbitmq:management  将其修改为自启动:dockerupdaterabbitmq--restart=always  以下为通过java代码进行创建交换机......
  • 【Java设计模式】装饰者设计模式
    目录1.装饰者模式(Wrapper)概念2.装饰者是什么?3.装饰者设计模式-参与者3.1组成3.1Demo1.Component(抽象构件)2.ConcreteComponent(具体构件)3.Decorator(抽象装饰类)4.ConcreteDecorator(具体装饰类)5.Test类:3.2总结4.JDK源码中的装饰者设计模式扩展:开闭原则1.装饰者模式(Wra......
  • VScode 创建Java项目
    1.点击view找到命令行输入java(ctrl+shift+P)src:一般是自己写的源代码的文件lib:外部引用库等其他的内容bin:二进制程序,用以存放未来的编译文件等  ......