`
huangjinjin520
  • 浏览: 67775 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

java并发之同步辅助类semaphore

阅读更多
semaphore(seməˌfôr)含义:

信号量就是可以声明多把锁(包括一把锁:此时为互斥信号量)。
举个例子:一个房间如果只能容纳5个人,多出来的人必须在门外面等着。如何去做呢?一个解决办法就是:房间外面挂着五把钥匙,每进去一个人就取走一把钥匙,没有钥匙的不能进入该房间而是在外面等待。每出来一个人就把钥匙放回原处以方便别人再次进入。



常用方法
acquire():获取信号量,信号量内部计数器减1
release():释放信号量,信号量内部计数器加1
tryAcquire():这个方法试图获取信号量,如果能够获取返回true,否则返回false
信号量控制的线程数量在声明时确定。例如:
    Semphore s = new Semphore(2);
一个例子
实现一个功能:一个打印队列,被三台打印机打印

package semaphore;

import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class PrintQueue {
//信号量
    private Semaphore semaphore;
   
    //是否空闲打印机
    private boolean freePrinters[];
   
    private Lock lockPrinters;
   
    public PrintQueue(){
    //初始化三个信号
        semaphore=new Semaphore(3);
        //三台空闲打印机
        freePrinters=new boolean[3];
        for (int i=0; i<3; i++){
            freePrinters[i]=true;
        }
        lockPrinters=new ReentrantLock();
    }
   
    public void printJob (Object document){
        try {
        //获取信号量
            semaphore.acquire();
           
            int assignedPrinter=getPrinter();
           
            Long duration=(long)(Math.random()*10);
            System.out.printf("%s: PrintQueue: Printing a Job in Printer %d during %d seconds\n",Thread.currentThread().getName(),assignedPrinter,duration);
            TimeUnit.SECONDS.sleep(duration);
           
            freePrinters[assignedPrinter]=true;
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            // Free the semaphore
            semaphore.release();           
        }
    }
    private int getPrinter() {
        int ret=-1;
       
        try {
            lockPrinters.lock();
            for (int i=0; i<freePrinters.length; i++) {
                if (freePrinters[i]){
                    ret=i;
                    freePrinters[i]=false;
                    break;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lockPrinters.unlock();
        }
        return ret;
    }
}

声明一个Job类,使用打印队列:
package semaphore;

public class Job implements Runnable {

     private PrintQueue printQueue;
     
      public Job(PrintQueue printQueue){
          this.printQueue=printQueue;
     }
     
      @Override
      public void run() {
         System.out.printf("%s: Going to print a job\n",Thread.currentThread().getName());
         printQueue.printJob(new Object());
         System.out.printf("%s: The document has been printed\n",Thread.currentThread().getName());       
     }
}

测试:
package semaphore;

public class MainCmd {
public static void main (String args[]){

PrintQueue printQueue=new PrintQueue();
//启动12个打印线程
        Thread thread[]=new Thread[12];
        for (int i=0; i<12; i++){
            thread[i]=new Thread(new Job(printQueue),"Thread "+i);
        }
        for (int i=0; i<12; i++){
            thread[i].start();
        }
}
}

需要注意的地方
1、对于信号量声明的临界区,虽然可以控制线程访问的数量,但是不能保证代码块之间是线程安全的。所以上面的例子在方法printJob()方法里面使用了锁保证数据安全性。
2、信号量也涉及到公平性问题。和锁公平性一样,这里默认是非公平的。可以通过构造器显示声明锁的公平性。
public Semaphore(int permits, boolean fair)

应用场景
流量控制,即控制能够访问的最大线程数。

海量视频获取 vue视频 angular视频
  • 大小: 207.9 KB
  • 大小: 39.9 KB
0
0
分享到:
评论

相关推荐

    java并发工具类(CountDownLatch+Semaphore+Exchanger)

    java并发工具类(CountDownLatch+Semaphore+Exchanger);java并发工具类(CountDownLatch+Semaphore+Exchanger);java并发工具类(CountDownLatch+Semaphore+Exchanger);java并发工具类(CountDownLatch+...

    java并发之并发工具类

    java并发之并发工具类,并发工具类有很多,这里主要介绍了CyclicBarrier、CountDownLatch、Semaphore、Exchanger

    java并发之Semaphore信号量.md

    Semaphore是计数信号量。Semaphore管理一系列许可证。每个acquire方法阻塞,直到有一个许可证可以获得然后拿走一个许可证;每个release方法增加一个许可证,这可能会释放一个阻塞的acquire方法。然而,其实并没有...

    java并发工具包 java.util.concurrent中文版用户指南pdf

    1. java.util.concurrent - Java 并发工具包 2. 阻塞队列 BlockingQueue 3. 数组阻塞队列 ArrayBlockingQueue 4. 延迟队列 DelayQueue 5. 链阻塞队列 LinkedBlockingQueue 6. 具有优先级的阻塞队列 ...

    03-并发与同步-semaphore1

    第三章 并发与同步:信号量夏文副教授哈尔滨工业大学(深圳)2021年秋季信号的介绍 (Introduction to Signals)同步(Synchroniz

    java并发工具包详解

    1. java.util.concurrent - Java 并发工具包 2. 阻塞队列 BlockingQueue 3. 数组阻塞队列 ArrayBlockingQueue 4. 延迟队列 DelayQueue 5. 链阻塞队列 LinkedBlockingQueue 6. 具有优先级的阻塞队列 ...

    龙果java并发编程完整视频

    第39节并发工具类Semaphore详解00:17:27分钟 | 第40节并发工具类Exchanger详解00:13:47分钟 | 第41节CountDownLatch,CyclicBarrier,Semaphore源码解析00:29:57分钟 | 第42节提前完成任务之FutureTask使用00:11:43...

    Java多线程之并发工具类

     主要参考资料:java并发编程的艺术、Java并发——同步工具类  二、CountDownLatch(同步倒数计数器)–不仅仅用于多线程  1.作用:允许一个或多个线程等待其他线程完成操作。  CountDownLatch的构造函数...

    Java并发编程原理与实战

    并发工具类Semaphore详解.mp4 并发工具类Exchanger详解.mp4 CountDownLatch,CyclicBarrier,Semaphore源码解析.mp4 提前完成任务之FutureTask使用.mp4 Future设计模式实现(实现类似于JDK提供的Future).mp4 Future...

    java线程并发semaphore类示例

    Java 5.0里新加了4个协调线程间进程的同步装置,它们分别是Semaphore, CountDownLatch, CyclicBarrier和Exchanger,本例主要介绍Semaphore,Semaphore是用来管理一个资源池的工具,可以看成是个通行证

    Java并发系列之Semaphore源码分析

    主要为大家详细介绍了Java并发系列之Semaphore源码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

    java并发核心Semaphore 的使用思路.docx

    Semaphore的初步使用 Semaphore是什么,能做什么? Semaphore 是 synchronized 的加强版,作用是控制线程的...直接看例子吧,这个例子包含3个类,一个是线程类,一个是 Semaphore 关键代码类,一个类是主main方法类:

    龙果 java并发编程原理实战

    第39节并发工具类Semaphore详解00:17:27分钟 | 第40节并发工具类Exchanger详解00:13:47分钟 | 第41节CountDownLatch,CyclicBarrier,Semaphore源码解析00:29:57分钟 | 第42节提前完成任务之FutureTask使用00:11:43...

    Java并发工具包java.util.concurrent用户指南中英文对照阅读版.pdf

    java.util.concurrent - Java 并发工具包 2. 阻塞队列 BlockingQueue 3. 数组阻塞队列 ArrayBlockingQueue 4. 延迟队列 DelayQueue 5. 链阻塞队列 LinkedBlockingQueue 6. 具有优先级的阻塞队列 ...

    通俗易懂学习java并发工具类-Semaphore,Exchanger

    主要介绍了java并发工具类-Semaphore,Exchanger,java并发工具类有很多,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,下面小编带大家来一起学习一下吧

    Java并发编程(学习笔记).xmind

    Java并发编程 背景介绍 并发历史 必要性 进程 资源分配的最小单位 线程 CPU调度的最小单位 线程的优势 (1)如果设计正确,多线程程序可以通过提高处理器资源的利用率来提升系统吞吐率 ...

    使用信号量(Semaphore)实现线程的同步

    使用信号量(Semaphore)实现线程的同步

    Java并发编程学习笔记

    7、并发工具类CountDownLatch 、CyclicBarrier和Semaphore底层实现原理 8、线程池原理和如何使用线程池 9、ThreadLocal 为什么会内存泄漏 10、Volatile底层实现原理 11、AQS源码分析 12、CAS原理分析和使用场景 13、...

    多线程(C++)同步Semaphore

    多线程(C++)同步Semaphore

Global site tag (gtag.js) - Google Analytics