本文主要是介绍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)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!