`

java多线程编程——同步器Semaphore(一)

阅读更多
网上关于解释Semaphore用法的代码很多,但是都不能运行或者运行错误。下面的例子是经过我自己运行过的。而且我详细的注释了下各个变量和方法的用途。希望对大家有用,一起研究。
import java.util.concurrent.Semaphore;

/**
 *
 * @author Administrator
 *
 */
public class PoolSemaphoreDemo {
	private static final int MAX_AVAILABLE = 5;
	private final Semaphore available = new Semaphore(MAX_AVAILABLE, true);

	public static void main(String[] args) {
		final PoolSemaphoreDemo pool = new PoolSemaphoreDemo();
		Runnable runner = new Runnable() {
			public void run() {
				try {
					Object o;
					o = pool.getItem();

					Thread.sleep(1000);// 表示该线程睡眠1秒钟,即改线程不去竞争cpu处理时间1秒钟

					pool.putItem(o);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		};
		// 将上述线程重复执行10次
		for (int i = 0; i < 10; i++) {
			Thread t = new Thread(runner, "t" + i);
			t.start();
		}
	}

	/**
	 * 从字符串池中取得最近一个可用的字符串资源,同时将标志位池中的状态设为true,表示有线程正在使用。
	 *
	 * @return
	 * @throws InterruptedException
	 */
	public Object getItem() throws InterruptedException {
		System.out.println("线程:" + Thread.currentThread().getName()
				+ "开始从字符串资源池中取数据");
		available.acquire();
		return getNextAvailableItem();
	}

	/**
	 * 将x对应的标志位池的状态修改为false,然后释放改字符串资源供其他线程读取
	 *
	 * @param x
	 */
	public void putItem(Object x) {
		if (markAsUnused(x)) {
			available.release();
			System.out.println("线程:" + Thread.currentThread().getName()
					+ "已经释放资源");
		}
	}

	// 需要循环取的字符串池
	protected Object[] items = { "AAA", "BBB", "CCC", "DDD", "EEE" };
	// 字符串池对应的标志位池,如果为true表示正在使用,其他线程不可用。如果为false,则表示其他线程可以用
	protected boolean[] used = new boolean[MAX_AVAILABLE];

	/**
	 * 根据标志位数组得到items中有效的字符串
	 *
	 * @return
	 */
	protected synchronized Object getNextAvailableItem() {
		for (int i = 0; i < MAX_AVAILABLE; ++i) {
			if (!used[i]) {
				used[i] = true;
				System.out.println("线程:" + Thread.currentThread().getName()
						+ "从字符串池中取得资源:" + items[i]);
				return items[i];
			}
		}
		return null;
	}

	/**
	 * 根据item将对应位置的标志位的值改为false
	 *
	 * @param item
	 * @return
	 */
	protected synchronized boolean markAsUnused(Object item) {
		for (int i = 0; i < MAX_AVAILABLE; ++i) {
			if (item == items[i]) {
				if (used[i]) {
					used[i] = false;
					System.out.println("线程:" + Thread.currentThread().getName()
							+ "开始向字符串池中放入资源:" + items[i]);
					return true;
				} else
					return false;
			}
		}
		return false;
	}

}


Semaphore的用途中需要注意的就是,当release()或者acquire()时,如果当前线程不能获取到资源,那么当前线程会阻塞。知道获取到资源为止,这点可以从输出结果中可以看到。

下面是运行结果

    线程:t0开始从字符串资源池中取数据
    线程:t0从字符串池中取得资源:AAA
    线程:t1开始从字符串资源池中取数据
    线程:t1从字符串池中取得资源:BBB
    线程:t3开始从字符串资源池中取数据
    线程:t3从字符串池中取得资源:CCC
    线程:t5开始从字符串资源池中取数据
    线程:t5从字符串池中取得资源:DDD
    线程:t7开始从字符串资源池中取数据
    线程:t7从字符串池中取得资源:EEE
    线程:t9开始从字符串资源池中取数据
    线程:t2开始从字符串资源池中取数据
    线程:t4开始从字符串资源池中取数据
    线程:t6开始从字符串资源池中取数据
    线程:t8开始从字符串资源池中取数据
    线程:t0开始向字符串池中放入资源:AAA
    线程:t0已经释放资源
    线程:t9从字符串池中取得资源:AAA
    线程:t1开始向字符串池中放入资源:BBB
    线程:t1已经释放资源
    线程:t3开始向字符串池中放入资源:CCC
    线程:t3已经释放资源
    线程:t2从字符串池中取得资源:BBB
    线程:t4从字符串池中取得资源:CCC
    线程:t5开始向字符串池中放入资源:DDD
    线程:t5已经释放资源
    线程:t7开始向字符串池中放入资源:EEE
    线程:t7已经释放资源
    线程:t6从字符串池中取得资源:DDD
    线程:t8从字符串池中取得资源:EEE
    线程:t9开始向字符串池中放入资源:AAA
    线程:t9已经释放资源
    线程:t4开始向字符串池中放入资源:CCC
    线程:t4已经释放资源
    线程:t2开始向字符串池中放入资源:BBB
    线程:t2已经释放资源
    线程:t8开始向字符串池中放入资源:EEE
    线程:t8已经释放资源
    线程:t6开始向字符串池中放入资源:DDD
    线程:t6已经释放资源
分享到:
评论

相关推荐

    java多线程教程——一个课件彻底搞清多线程

    Java多线程是Java编程中的核心概念,它允许程序同时执行多个任务,从而提高应用程序的效率和响应性。本教程将深入讲解Java线程的相关知识,包括进程与线程的基本概念、线程的创建和启动、多线程的互斥与同步、线程...

    Java多线程运算集合

    - Java多线程编程涉及多个方面的知识和技术,从基本的线程创建到高级的同步机制,都是开发高效、可靠的多线程应用程序所必需的。 - 正确理解和使用这些技术对于提高程序性能、避免死锁等问题至关重要。

    并发编程——并发工具类.pdf

    并发工具类则是Java中用于支持多线程协作和同步控制的一系列工具,它们可以简化并发控制逻辑,提高开发效率,并且减少因并发编程带来的错误。 #### 标题与描述解析 标题“并发编程——并发工具类.pdf”预示了文档...

    Java程序员面试宝典——2012版

    《Java程序员面试宝典——2012版》是一份针对Java程序员面试的全面指南,旨在帮助准备面试的程序员深入理解和掌握Java的核心概念和技术。以下是对该文档标题、描述及部分内容涉及的重要知识点的详细解析: ### Java...

    多线程面试题

    多线程面试题往往会围绕线程的概念、特性、线程安全、锁机制以及多线程编程中可能遇到的问题和解决方案进行提问。 线程是操作系统能够进行运算调度的最小单位,它是进程中的一个实体,是被包含在进程之中的。一个...

    Semaphore 源码解析

    Semaphore是Java并发编程中的一种重要工具,主要用于控制并发线程的访问权限,实现限流或资源的互斥访问。在高并发场景下,Semaphore能够有效地防止过多的线程同时访问共享资源,从而避免系统资源耗尽,提高系统性能...

    一个简单的线程同步实例

    线程同步是多线程编程中的重要概念,它主要用于解决多个线程并发访问共享资源时可能出现的竞争条件问题,确保数据的正确性和程序的稳定性。在Java等编程语言中,线程同步可以通过多种方式实现,本实例将探讨其中的几...

    73道Java面试题合集-多线程与进程

    这些知识点涵盖了Java多线程与进程的基础和进阶内容,理解并掌握它们对于解决实际的并发问题以及应对面试挑战都极其重要。通过深入学习和实践,开发者能够编写出更加高效、安全的多线程Java应用程序。

    Java实现进程同步

    Java作为一种强大的多线程编程语言,提供了丰富的API来支持进程同步。本篇文章将深入探讨如何使用Java实现“生产者-消费者”问题的进程同步。 生产者-消费者问题是多线程设计模式中的一个经典案例,它模拟了两个...

    java葵花宝典——各种问题详细解答

    4. **多线程** - **并发编程**:理解线程的基本概念,如何创建和管理线程,以及同步机制(如synchronized、volatile、Lock接口)的使用,是开发高并发应用的基础。 - **线程池**:ExecutorService和...

    Java并发编程实践.rar

    介绍Java并发编程中常用的集合框架,如ConcurrentHashMap、CopyOnWriteArrayList等,它们是如何在多线程环境下保证数据一致性与高效性的。 第五章:线程池 分析ExecutorService和ThreadPoolExecutor,解释如何配置...

    Java并发编程实践

    总之,《Java并发编程实践》是一本全面解析Java并发编程的指南,它涵盖了从基础到高级的并发知识,帮助开发者构建高效、稳定的多线程应用程序。通过深入学习和实践,开发者可以更好地应对并发挑战,编写出更加健壮、...

    The java.util.concurrent Synchronizer Framework

    本文围绕Java并发编程中的一个关键组件——java.util.concurrent Synchronizer Framework(同步器框架)进行探讨。该框架主要基于AbstractQueuedSynchronizer(AQS)类,为同步器的实现提供了一种通用机制,包括同步...

    java面试——深圳-商汤科技-Java高级.zip

    2. **多线程**:Java提供了强大的多线程支持,包括Thread类和Runnable接口。了解线程同步机制,如synchronized关键字、wait/notify机制、Lock锁、ReentrantLock等,以及并发工具类如ExecutorService、Semaphore、...

    115个Java面试题和答案——终极列表(下)-word版本

    6. **多线程**:Java提供了丰富的多线程支持,如Thread类、Runnable接口、synchronized关键字、Lock接口等。面试中会考察线程同步、死锁、线程池的使用。 7. **IO流**:Java的IO系统是基于流的,包括字符流和字节流...

    java面试——深圳-中国平安-Java中级.zip

    3. **多线程**: - **线程创建**:使用Thread类和Runnable接口创建线程。 - **同步机制**:synchronized、Lock、volatile关键字的应用及其原理。 - **并发工具类**:如Semaphore、CountDownLatch、CyclicBarrier...

    java多线程源码-SmartSocket:SmartSocket是可扩展的开源Java和PHP套接字服务器引擎。其目的是使创建多用户应用程序

    Java多线程源码分析——以SmartSocket为例 在Java编程中,多线程技术是构建高效、可扩展的应用程序的关键。SmartSocket是一款基于Java和PHP的开源套接字服务器引擎,它允许开发者轻松地创建支持多用户的网络应用...

    java面试——杭州-阿里云-Java中级.zip

    3. **多线程**:掌握线程的创建方式(Thread类、Runnable接口)、线程同步机制(synchronized关键字、wait/notify、Lock接口及其实现类)、并发工具类(如CountDownLatch、CyclicBarrier、Semaphore)以及线程池...

    Java并发编程实战(中文版).7z

    这本书全面地介绍了如何在Java平台上高效、安全地编写多线程程序,帮助读者理解并解决并发编程中的各种挑战。 首先,我们需要理解“并发”这个概念。并发是指在一段时间内,多个任务可以同时进行或交替执行。在单...

    JAVA课程总复习

    7. **多线程**:介绍线程的概念,创建线程的方式(继承Thread类和实现Runnable接口),线程同步和通信机制(如synchronized关键字、wait/notify、Semaphore等)。 8. **反射**:探讨如何在运行时动态获取类的信息并...

Global site tag (gtag.js) - Google Analytics