`
qtlkw
  • 浏览: 301597 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

java Semaphore信号量用法

    博客分类:
  • JAVA
 
阅读更多
如果一个线程要访问一个共享资源,它必须先获得信号量。如果信号量的内部计数器大于0,信号量减1,然后允许访问这个共享资源。计数器大于0意味着有可以使用的资源,线程允许使用其中一个资源。

否则,如果信号量的计数器等于0,信号量将会把线程置入休眠直至计数器大于0,计数器等于0的时候意味着所有的共享资源已经被其他线程使用了,所以需要访问这个共享资源的线程必须等待。

当线程使用完某个共享资源时,信号量必须被释放,以便其他线程能够访问共享资源。释放操作将使信号量的内部计数器增加1。

资源: 打印队列
import java.util.concurrent.Semaphore;

/**
 * Created by Administrator.
 */
public class PrintQueue {
    private final Semaphore semaphore;

    public PrintQueue(){
        semaphore = new Semaphore(1);
    }

    public void printJob(Object document){
        try{
            semaphore.acquire();
            long duration = (long)(Math.random() * 10);
            System.out.printf("%s: PrintQueue: Printing a Job during %d seconds\n", Thread.currentThread()
            .getName(), duration
            );
            Thread.sleep(duration);
        }catch(InterruptedException e){
            e.printStackTrace();
        }finally{
            semaphore.release();
            System.out.printf("%s: Done the print job\n", Thread.currentThread().getName());
        }
    }
}


Runnable job:
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());
    }
}


Main:
public class Main {
    public static void main(String args[]){
        PrintQueue printQueue = new PrintQueue();
        Thread thread[] = new Thread[10];
        for(int i=0; i<10; i++){
            thread[i] = new Thread(new Job(printQueue), "Thread " + i);
        }

        for(int i=0; i<10; i++){
            thread[i].start();
        }
    }
}


用信号量来保护一个资源的多个副本。
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * Created by Administrator.
 */
public class PrintQueue {
    private final 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{
            semaphore.release();
            System.out.printf("%s: Done the print job\n", Thread.currentThread().getName());
        }
    }

    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;
    }
}

分享到:
评论

相关推荐

    Java中Semaphore(信号量)的使用方法

    主要介绍了Java中Semaphore(信号量)的使用方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

    SemaphoreTest

    代码清晰的展示了生产者与消费者模式,以及Java中semaphore信号量的使用方法

    带你看看Java的锁(二)-Semaphore

    带你看看Java的锁-Semaphore前言简介使用源码分析类结构图SyncNonfairSyncFairSyncSemaphore 构造函数Semaphore 成员方法获取释放总结 前言 简介 Semaphore 中文称信号量,它和ReentrantLock 有所区别,...

    java多线程每个线程挨着打印ABC的4种实现方式

    java多线程每个线程挨着打印ABC的4种实现方式,有4个线程t1、t2、t3、t4,t1打印A后t2打印A再t3打印A再t4打印A,然后从新回到t1打印B再t2打印B...t4打印B... ...欢迎大家一起交流,使用更多的方法来实现。

    producers-consumers-rmi:基于Java RMI的分布式生产者-消费者问题的实现

    作为实践的一种手段,实现了一对信号量(即公平和不公平的信号量),它们仅使用Java的synchronized原语。 信号量 有两种可用的信号量: FairSemaphore和UnfairSemaphore 。 两者都是abstract class Semaphore子类,...

    JAVA并发编程-2-线程并发工具类

    JAVA并发编程-2-线程并发工具类一、Fork/Join1、分而治之与工作密取2、使用标准范式3、Fork/Join的同步用法4、Fork/Join的异步用法二、CountDownLatch三、CyclicBarrier四、Semaphore信号量五、Exchanger ...

    操作系统原理课程设计读者-写者问题的实现.doc

    通过使用记录型信号量,可以实现读者优先和写者优先的读者-写者问题。 知识点3: 读者优先算法 读者优先算法是解决读者-写者问题的一种方法。该算法通过设置两个互斥信号量:rwmutex 和 rmutex,用于写者与其他读者...

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

    信号量(Semaphore) 用来控制同时访问某个特定资源的操作数量,或者同时执行某个指定操作的数量 管理者一组虚拟的许可。acquire获得许可(相当于P操作),release释放许可(相当于V操作) 应用...

    个人总结的深入java多线程开发

    6)信号量Semaphore 31 7)ReentrantLock可重入的互斥锁定 Lock 32 8)阻塞队列BlockingQueue 34 9)已完成任务队列CompletionService 36 10)计时器CountDownLatch 37 11)周期性同步工具CyclicBarrier 38 12)异步计算的...

    这就是标题—— JUC.pdf

    Semaphore(信号量,流量控制) ReentrantReadWriteLock (读写锁) BlockingQueue(阻塞队列) 线程池 池化技术 线程池的优势 线程池的特点 线程池三大方法 线程池七大参数 线程池四种拒绝策略 ForkJoin 异步回调 ...

    java核心知识点整理.pdf

    25 JAVA8 与元数据.................................................................................................................................25 2.4. 垃圾回收与算法 .................................

    Java并发编程实战

    5.5.3 信号量82 5.5.4 栅栏83 5.6 构建高效且可伸缩的结果缓存85 第二部分 结构化并发应用程序 第6章 任务执行93 6.1 在线程中执行任务93 6.1.1 串行地执行任务94 6.1.2 显式地为任务创建线程94 6.1.3 ...

    JAVA核心知识点整理(有效)

    25 JAVA8 与元数据.................................................................................................................................25 2.4. 垃圾回收与算法 .................................

    javaSE代码实例

    17.4 信号量的使用 393 17.4.1 Semaphore类简介 393 17.4.2 Semaphore类的具体使用 394 17.5 队列 396 17.5.1 Queue接口介绍 396 17.5.2 PriorityQueue类的知识与使用 397 17.5.3 BlockingQueue接口...

Global site tag (gtag.js) - Google Analytics