java并发包:信号量

你的名字 2024-02-17 21:17 181阅读 0赞

本文转载至:http://blog.csdn.net/a910626/article/details/51900947

信号量为多线程协作提供了更为强大的控制方法。广义上说,信号量是对锁的扩展。无论是内部锁synchronized还是重入锁ReentrantLock,一次都只允许一个线程访问一个资源,而信号量却可以指定多个线程,同时访问某一个资源。信号量主要提供了一下构造函数:

  1. Semaphore(int permits)
  2. Creates a Semaphore with the given number of permits and nonfair fairness setting.
  3. Semaphore(int permits, boolean fair)
  4. Creates a Semaphore with the given number of permits and the given fairness setting.第二个参数指定是否公平

在构造信号量对象时,必须要指定信号量的准入数,即同时能申请多少个许可。当每个线程每次只申请一个许可时,这就相当于指定了同时有多少个线程可以访问某一个资源。信号量的主要逻辑方法有:

  1. void acquire()
  2. Acquires a permit from this semaphore, blocking until one is available, or the thread is interrupted.
  3. void acquire(int permits)
  4. Acquires the given number of permits from this semaphore, blocking until all are available, or the thread is interrupted.
  5. void acquireUninterruptibly()
  6. Acquires a permit from this semaphore, blocking until one is available.
  7. void acquireUninterruptibly(int permits)
  8. Acquires the given number of permits from this semaphore, blocking until all are available.
  9. int availablePermits()
  10. Returns the current number of permits available in this semaphore.
  11. int drainPermits()
  12. Acquires and returns all permits that are immediately available.
  13. protected Collection<Thread> getQueuedThreads()
  14. Returns a collection containing threads that may be waiting to acquire.
  15. int getQueueLength()
  16. Returns an estimate of the number of threads waiting to acquire.
  17. boolean hasQueuedThreads()
  18. Queries whether any threads are waiting to acquire.
  19. boolean isFair()
  20. Returns true if this semaphore has fairness set true.
  21. protected void reducePermits(int reduction)
  22. Shrinks the number of available permits by the indicated reduction.
  23. void release()
  24. Releases a permit, returning it to the semaphore.
  25. void release(int permits)
  26. Releases the given number of permits, returning them to the semaphore.
  27. String toString()
  28. Returns a string identifying this semaphore, as well as its state.
  29. boolean tryAcquire()
  30. Acquires a permit from this semaphore, only if one is available at the time of invocation.
  31. boolean tryAcquire(int permits)
  32. Acquires the given number of permits from this semaphore, only if all are available at the time of invocation.
  33. boolean tryAcquire(int permits, long timeout, TimeUnit unit)
  34. Acquires the given number of permits from this semaphore, if all become available within the given waiting time and the current thread has not been interrupted.
  35. boolean tryAcquire(long timeout, TimeUnit unit)
  36. Acquires a permit from this semaphore, if one becomes available within the given waiting time and the current thread has not been interrupted.

这里只讲几个常用的方法:

  • acquire() 方法尝试获得一个准入的许可。若无法获得,则线程会等待,直到有线程释放一个许可或者当前线程被中断。
  • acquireUninterruptibly方法和acquire方法类似,但是不响应中断。
  • tryAcquire尝试获得一个许可,如果成功返回true,失败返回false,它不会进行等待,立即返回。
  • release用于在线程访问资源结束后,释放一个许可,以使其他等待许可的线程可以进行资源访问

一个案例:

  1. /**
  2. * Created by niehongtao on 16/7/12.
  3. * 3.1.3允许多个线程同时访问:信号量
  4. */
  5. public class SemapDemo implements Runnable {
  6. final Semaphore semp = new Semaphore(5);
  7. @Override
  8. public void run() {
  9. try {
  10. semp.acquire();
  11. // 模拟耗时操作
  12. Thread.sleep(5000);
  13. System.out.println(Thread.currentThread().getId() + ":done");
  14. semp.release();
  15. } catch (InterruptedException e) {
  16. e.printStackTrace();
  17. }
  18. }
  19. public static void main(String[] args) {
  20. ExecutorService exec = Executors.newFixedThreadPool(20);
  21. SemapDemo demo = new SemapDemo();
  22. for (int i = 0; i < 20; i++) {
  23. exec.execute(demo);
  24. }
  25. }
  26. }

上述代码中,15、16行为临界区,程序会限制执行这段代码的线程数。这里在第7行,声明了一个包含5个许可的信号量。这就意味着同时可以有5个线程进入代码段15,16行。申请信号量使用semp.acquire,在离开时,务必使用semp.release释放信号量。这就和释放锁一个道理。

发表评论

表情:
评论列表 (有 0 条评论,181人围观)

还没有评论,来说两句吧...

相关阅读

    相关 Java发包

    Java线程:新特征-线程池 Sun在Java5中,对Java线程的类库做了大量的扩展,其中线程池就是Java5的新特征之一,除了线程池之外,还有很多多线程相关的内容,为多线