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

java多线程之Semaphore信号量详解

阅读更多
原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。http://ketqi.blog.51cto.com/1130608/1127274
   信号量在操作系统中一般用来管理数量有限的资源.每类资源有一个对应的信号量.信号量的值表示资源的可用数量.在使用资源时,要先从该信号量上获取一个使用许可.成功获取许可之后,资源可用数量减1.在持有许可期,使用者可以对获取资源进行操作.完成对资源的使用之后,需要在信号量上释放一个许可,资源可用数加1,允许其他使用者获取资源.当资源可用数为0的时候,需要获取资源的线程以阻塞的方式来等待资源变为可用,或者过段时间之后再检查资源是否变为可用.

   在java中有相应的Semaphore实现类,在创建Semaphore类的对象时指定资源的可用数,通过acquire方法以阻塞式的方式获取许可,而tryAcquire方法以非阻塞式的方式来获取许可.当需要释放许可时,使用release方法.Semaphore类也支持同时获取和释放多个资源的许可.通过acquire方法获取许可的过程是可以被中断的.如果不希望被中断,那么可以使用acquireUninterruptibly方法.Semaphore也支持在分配许可时使用公平模式,通过把构造方法的第二个参数设置为true来使用该模式.在公平模式下,当资源可用时,等待线程按照调用acquire方法申请资源的顺序依次获取许可.在进行资源管理时,一般使用公平模式,以避免造成线程饥渴问题.需要注意的是获取资源时,通过synchronized关键词或锁声明同步.这是因为Semaphore类只是一个资源数量的抽象表示,并不负责管理资源对象本身,可能有多个线程同时获取到资源使用许可,因此需要使用同步机制避免数据竞争.

package semaphore;

import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
import java.util.concurrent.locks.ReentrantLock;

public class SemaphoreDemo2 {
    /** 可重入锁,对资源列表进行同步 */
    private final ReentrantLock lock = new ReentrantLock();
    /** 信号量 */
    private final Semaphore semaphore;
    /** 可使用的资源列表 */
    private final LinkedList<Object> resourceList = new LinkedList<Object>();

    public SemaphoreDemo2(Collection<Object> resourceList) {
        this.resourceList.addAll(resourceList);
        this.semaphore = new Semaphore(resourceList.size(), true);
    }

    /**
     * 获取资源
     *
     * @return 可用的资源
     * @throws InterruptedException
     */
    public Object acquire() throws InterruptedException {
        semaphore.acquire();

        lock.lock();
        try {
            return resourceList.pollFirst();
        } finally {
            lock.unlock();
        }
    }

    /**
     * 释放或者归还资源
     *
     * @param resource 待释放或归还的资源
     */
    public void release(Object resource) {
        lock.lock();
        try {
            resourceList.addLast(resource);
        } finally {
            lock.unlock();
        }

        semaphore.release();
    }

    public static void main(String[] args) {
        //准备2个可用资源
        List<Object> resourceList = new ArrayList<Object>();
        resourceList.add("Resource1");
        resourceList.add("Resource2");

        //准备工作任务
        final SemaphoreDemo2 demo = new SemaphoreDemo2(resourceList);
        Runnable worker = new Runnable() {
            @Override
            public void run() {
                Object resource = null;
                try {
                    //获取资源
                    resource = demo.acquire();
                    System.out.println(Thread.currentThread().getName() + "\twork   on\t" + resource);
                    //用resource做工作
                    Thread.sleep(1000);
                    System.out.println(Thread.currentThread().getName() + "\tfinish on\t" + resource);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    //归还资源
                    if (resource != null) {
                        demo.release(resource);
                    }
                }
            }
        };

        //启动9个任务
        ExecutorService service = Executors.newCachedThreadPool();
        for (int i = 0; i < 9; i++) {
            service.submit(worker);
        }
        service.shutdown();
    }
}

分享到:
评论

相关推荐

    JAVA 多线程之信号量(Semaphore)实例详解

    **JAVA 多线程之信号量Semaphore实例详解** 在Java多线程编程中,信号量Semaphore是一种非常重要的同步工具,用于控制对公共资源的访问。Semaphore类位于`java.util.concurrent`包下,它允许我们限制同时访问特定...

    Java多线程Semaphore工具的使用详解.rar

    Java多线程编程是开发高并发应用的关键技术之一,Semaphore工具是Java并发包(java.util.concurrent)中的一个重要组件,用于控制同时访问特定资源的线程数量。本篇将深入讲解Semaphore的基本概念、工作原理以及如何...

    Java并发编程Semaphore计数信号量详解

    Java并发编程Semaphore计数信号量详解 Java并发编程中,Semaphore(信号量)是一种高效的同步机制,允许一定数量的线程访问某个资源。在本文中,我们将详细介绍Java并发编程Semaphore计数信号量的工作原理和应用。 ...

    java多线程设计模式详解

    此外,还可以使用Semaphore信号量、CountDownLatch倒计时锁、CyclicBarrier同步屏障等工具类。 以上是部分Java多线程设计模式的概述,每个模式都有其适用场景和优缺点。实际开发中,开发者应根据需求选择合适的模式...

    java+多线程+同步详解源码整理

    - **Semaphore信号量**:用于控制同时访问特定资源的线程数量。 - **CyclicBarrier和CountDownLatch**:协调多个线程之间的同步,让它们在某个点一起开始或等待。 4. **死锁** 当两个或更多线程互相等待对方释放...

    java多线程设计模式详解+源码

    3. **线程同步**:为避免多线程环境中的数据不一致性,Java提供了多种同步机制,如synchronized关键字、Lock接口(ReentrantLock)、Semaphore信号量、CountDownLatch倒计时锁和CyclicBarrier同步屏障等。...

    java多线程设计模式详解(PDF及源码)

    线程同步机制,如synchronized关键字、Lock接口、Semaphore信号量等,用于解决多线程间的竞态条件和数据一致性问题。死锁预防则涉及资源的合理分配和线程间的协作,避免多个线程互相等待对方释放资源导致无法继续...

    JAVA多线程设计模式详解

    11. 信号量模式:Semaphore类提供了一种控制同时访问特定资源的线程数量的方法,用于限流或同步。 12. 计数器模式:用Atomic类如AtomicInteger、AtomicLong实现线程安全的计数操作,避免synchronized的开销。 全书...

    JAVA多线程编程详解-详细操作例子

    Java并发包`java.util.concurrent`提供了如`Semaphore`(信号量)、`CountDownLatch`(计数器)、`CyclicBarrier`(回环栅栏)等工具,它们是设计来协助多线程间的协作和同步的。 理解并熟练运用这些知识点,可以...

    C#多线程之Semaphore用法详解

    初始信号量表示Semaphore启动时已经存在的可用信号量数量,而最大信号量则是Semaphore能够容纳的最大信号量。在上述示例中,Semaphore初始化为(0, 1),这意味着一开始没有可用信号量,最大也只能有一个信号量。 `...

    linux信号量详解

    ### Linux信号量详解 #### 一、信号量概念与历史 1965年,E.W.Dijkstra引入了信号量的概念,这是一种操作系统中用于实现进程间互斥和同步的重要机制。信号量本质上是一个包含了非负整型变量的数据结构,伴随着两个...

    java中的多线程实例详解(自己去运行看结果)

    (`java.util.concurrent` 包) 提供了高级线程管理工具,如`ExecutorService`用于管理和控制线程池,`CountDownLatch`用于同步多个线程,`CyclicBarrier`让一组线程等待其他线程到达屏障点,以及`Semaphore`进行信号...

    java多线程设计模式详解PDF及源码

    5. **同步机制**:Java提供了多种同步机制,包括`synchronized`关键字、`Lock`接口(如`ReentrantLock`)、`Semaphore`信号量和`Condition`条件对象。它们用于控制对共享资源的访问,防止数据不一致性和死锁。 6. *...

Global site tag (gtag.js) - Google Analytics