Concurrent - Semaphore - Semaphore(int permits)

2023-10-11 20:20

本文主要是介绍Concurrent - Semaphore - Semaphore(int permits),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

原创转载请注明出处:http://agilestyle.iteye.com/blog/2342878

 

Semaphore所提供的功能完全是synchronized关键字的升级版,但它提供的功能更加的强大和方便,主要的作用是控制线程并发的数量

Semaphore(int permits)


 

设置permits为1

Service.java

package org.fool.java.concurrent.semaphore;import java.util.concurrent.Semaphore;public class Service {private Semaphore semaphore = new Semaphore(1);public void testMethod() {try {semaphore.acquire();System.out.println(Thread.currentThread().getName() + " begin timer=" + System.currentTimeMillis());Thread.sleep(5000);System.out.println(Thread.currentThread().getName() + " end timer=" + System.currentTimeMillis());semaphore.release();} catch (InterruptedException e) {e.printStackTrace();}}
}

Note:

permits代表同一时间内,最多允许多少个线程同时执行acquire()和release()之间的代码。

本例设置为1,所以最多只有1个线程同时执行acquire()和release()之间的代码。

ThreadA.java

package org.fool.java.concurrent.semaphore;public class ThreadA implements Runnable {private Service service;public ThreadA(Service service) {this.service = service;}@Overridepublic void run() {service.testMethod();}
}

ThreadB.java

package org.fool.java.concurrent.semaphore;public class ThreadB implements Runnable {private Service service;public ThreadB(Service service) {this.service = service;}@Overridepublic void run() {service.testMethod();}
}

ThreadC.java

package org.fool.java.concurrent.semaphore;public class ThreadC implements Runnable {private Service service;public ThreadC(Service service) {this.service = service;}@Overridepublic void run() {service.testMethod();}
}

SemaphoreTest.java

package org.fool.java.concurrent.semaphore;public class SemaphoreTest {public static void main(String[] args) {Service service = new Service();Thread a = new Thread(new ThreadA(service));Thread b = new Thread(new ThreadA(service));Thread c = new Thread(new ThreadA(service));a.setName("A");b.setName("B");c.setName("C");a.start();b.start();c.start();}
}

Run


Note:

private Semaphore semaphore = new Semaphore(1);

由于定义了最多1个线程执行acquire()和release()之间的代码,所以打印的结果就是3个线程是同步的,线程A执行结束的时间和线程B执行开始的时间相同,线程B执行结束的时间和线程C还行开始的时间相同。

 

修改Service.java,设置permits为2

private Semaphore semaphore = new Semaphore(2);

再次Run SemaphoreTest


Note:

由于定义了最多2个线程执行acquire()和release()之间的代码,所以线程A和线程B执行开始的时间是相同的,需要注意的是,对Semaphore的构造方法传递的参数permits值如果大于1时,该类并不能保证线程的安全性,因为还是有可能会出现多个线程共同访问实例变量,导致出现脏读。

 

Semaphore(int permits, boolean fair)

有些时候,获得permits的顺序与线程启动的顺序有关,这时信号量就要分为公平和非公平的。

公平信号量是获得锁的顺序与线程启动的顺序有关,但不代表100%地获得信号量,仅仅是在概率上能得到保证。

非公平信号量即获得锁的顺序与线程启动的顺序无关。

Service.java

package org.fool.java.concurrent.semaphore.fair;import java.util.concurrent.Semaphore;public class Service {private boolean isFair = false;private Semaphore semaphore = new Semaphore(1, isFair);public void testMethod() {try {semaphore.acquire();System.out.println(Thread.currentThread().getName());} catch (InterruptedException e) {e.printStackTrace();} finally {semaphore.release();}}
}

Note:

设置了非公平信号量

private boolean isFair = false;

 

ThreadA.java

package org.fool.java.concurrent.semaphore.fair;public class ThreadA implements Runnable {private Service service;public ThreadA(Service service) {this.service = service;}@Overridepublic void run() {System.out.println(Thread.currentThread().getName() + " invoked...");service.testMethod();}
}

FairTest.java

package org.fool.java.concurrent.semaphore.fair;public class FairTest {public static void main(String[] args) {Service service = new Service();Thread a = new Thread(new ThreadA(service));a.start();for(int i = 0; i < 4; i++) {new Thread(new ThreadA(service)).start();}}
}

 

Run

非公平信号量运行的效果是线程启动的顺序与调用semaphore.acquire()的顺序无关,也就是线程先启动了并不代表获得permits


 

修改Service.java,设置公平信号量

private boolean isFair = true;

 

再Run

公平信号量运行的效果是线程启动的顺序与调用semaphore.acquire()的顺序有关,也就是先启动的线程优先获得permits

 

 

 

 

 

 

 

这篇关于Concurrent - Semaphore - Semaphore(int permits)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/190580

相关文章

Python 中考虑 concurrent.futures 实现真正的并行计算

Python 中考虑 concurrent.futures 实现真正的并行计算 思考,如何将代码所要执行的计算任务划分成多个独立的部分并在各自的核心上面平行地运行。 Python 的全局解释器锁(global interpreter lock,GIL)导致没办法用线程来实现真正的并行​,所以先把这种方案排除掉。另一种常见的方案,是把那些对性能要求比较高的(performance-critica

【C语言】---- 基本数据类型(char、int、float)

1 基本数据类型 C语言中的基本数据类型包括整型、浮点型和字符型,每种类型都有不同的存储大小和表示范围。以下是它们的常见表示形式和特点: 1.1 字符型 char类型用于表示单个字符,通常用于表示文本数据。char类型也被用来存储字符,但也可以用来存储较小的整数。在C语言中,char类型的大小一般为1字节(8位)。char类型可以是有符号的或无符号的,这取决于编译器和平台的实现。 1.2

如何简便的将List<Integer>转换成int[]?

使用Java 8的流(Streams)  ArrayList<Integer> list = new ArrayList<>();int[] intArray = list.stream().mapToInt(Integer::intValue).toArray();  若是maven项目可使用Apache Commons Lang库 <dependency> <groupId>

Syntax error on token int, VariableDeclaratorId expected after this token

Syntax error on token "int", VariableDeclaratorId expected after this token,看图,   <item name=" " type="id"/>; 这个的name没有,看图 删掉这行就行了,R.java就不会报错了!!!!!!!!!!!

java 多线程 CountDownLatch、CyclicBarrier、Semaphore

在java 1.5中,提供了一些非常有用的辅助类来帮助我们进行并发编程,比如CountDownLatch,CyclicBarrier和Semaphore,今天我们就来学习一下这三个辅助类的用法。   以下是本文目录大纲:   一.CountDownLatch用法   二.CyclicBarrier用法   三.Semaphore用法   若有不正之处请多多谅解,并欢迎批评指正。

MySQL数据类型 int(M)中M含义

int(M)我们先来拆分,int是代表整型数据那么中间的M应该是代表多少位了,后来查mysql手册也得知了我的理解是正确的,下面我来举例说明。 MySQL 数据类型中的 integer types 有点奇怪。你可能会见到诸如:int(3)、int(4)、int(8) 之类的 int 数据类型。刚接触 MySQL 的时候,我还以为 int(3) 占用的存储空间比 int(4) 要小, int(4)

int数组和String字符串如何相互转化?

使用Java 8的Stream API 例如 int[] nums={1,2,3}  转化为 “123” String str = Arrays.stream(nums)// 将int转换为String .mapToObj(String::valueOf)// 使用分隔符连接 若需要,则Collectors.joining(",").collect(Collectors.joining());

java多线程学习--java.util.concurrent

题记:util和concurrent 包是后续重点先看的和学习的模块 原文地址:http://www.cnblogs.com/sunhan/p/3817806.html   CountDownLatch,api 文档:http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/CountDownLatch.html

golang string转int,int转string

这个写业务代码的时候非常常用。 1、常用提出来 string转成int:int, err := strconv.Atoi(string)string转成int64:int64, err := strconv.ParseInt(string, 10, 64)int转成string:string := strconv.Itoa(int)int64转成string:string :=

C语言 int uint16_t 踩坑记录

使用 uint16_t 存储 int的负数,有可能读出来是65535 ? 是的,如果你尝试使用 uint16_t 类型来存储一个负数 int 值,你可能会得到 65535。这是因为 uint16_t 是一个无符号的16位整数类型,它的取值范围是从 0 到 65535(即 0 到 2^16 - 1)。当将一个负数强制转换为 uint16_t 时,实际上会发生一种称为“类型提升”的过程,这个过程会将