多线程并发知识点(一)

来源:互联网 发布:java入门的好书 编辑:程序博客网 时间:2024/05/01 12:35

Semaphore类

JDK API中描述为:一个计数信号量。从概念上讲,信号量维护了一个许可集。如有必要,在许可可用前会阻塞每一个 acquire(),然后再获取该许可。每个 release() 添加一
个许可,从而可能释放一个正在阻塞的获取者。但是,不使用实际的许可对象,Semaphore 只对可用许可的号码进行计数,并采取相应的行动。
Semaphore 通常用于限制可以访问某些资源(物理或逻辑的)的线程数目。将信号量初始化为 1,使得它在使用时最多只有一个可用的许可,从而可用作一个相互排斥的锁。这通常也称为二进制信号量,因为它只能有两种状态:一个可用的许可,或零个可用的许可。按此方式使用时,二进制信号量具有某种属性(与很多 Lock 实现不同),即可以由线程释放“锁”,而不是由所有者(因为信号量没有所有权的概念)。在某些专门的上下文(如死锁恢复)中这会很有用。
package com.jjyy.customer;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.Semaphore;import java.util.concurrent.SynchronousQueue;/*Semaphore与SynchronousQueue的混合使用。由于Semaphore只有1个许可权,所以谁先拿到谁执行,然后释放,保证依次执行,用锁也行,只要保证一个线程执行即可SynchronousQueue是必须有其他线程取的动作,这样一一对应*/public class Test {public static void main(String[] args) {//定义一个许可权为1的信号灯final Semaphore semaphore = new Semaphore(1);//产生的结果无序final SynchronousQueue<String> queue = new SynchronousQueue<String>();/*//产生10个线程for(int i=0;i<10;i++){new Thread(new Runnable(){@Overridepublic void run() {try {semaphore.acquire();//获取许可String input = queue.take();//获取并移除此队列的头String output = TestDoIT.doSome(input);System.out.println(Thread.currentThread().getName()+ ":" + output);semaphore.release();//释放许可} catch (InterruptedException e) {e.printStackTrace();}}}).start();}*/ExecutorService executor = Executors.newFixedThreadPool(10);for (int i = 0; i < 10; i++) {executor.execute(new Runnable() {public void run() {try {semaphore.acquire();//获取许可String input = queue.take();//获取并移除此队列的头String output = TestDoIT.doSome(input);System.out.println(Thread.currentThread().getName()+ ":" + output);semaphore.release();//释放许可} catch (Exception e) {e.printStackTrace();}}});}System.out.println("begin:"+(System.currentTimeMillis()/1000));for(int i=0;i<10;i++){  //这行不能改动String input = i+"";  //这行不能改动try {queue.put(input);//将指定元素添加到此队列} catch (InterruptedException e) {e.printStackTrace();}}}}//不能改动此TestDo类class TestDoIT {public static String doSome(String input){try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}String output = input + ":"+ (System.currentTimeMillis() / 1000);return output;}}

执行结果:
begin:1439963505pool-1-thread-1:0:1439963506pool-1-thread-2:1:1439963507pool-1-thread-3:2:1439963508pool-1-thread-4:3:1439963509pool-1-thread-5:4:1439963510pool-1-thread-6:5:1439963511pool-1-thread-7:6:1439963512pool-1-thread-9:7:1439963513pool-1-thread-8:8:1439963514pool-1-thread-10:9:1439963515


0 0
原创粉丝点击