Java并发学习之十六——线程同步工具之信号量(Semaphores)

本文是学习网络上的文章时的总结,感谢大家无私的分享。

当一个线程想要访问某个共享资源,首先,它必须获得semaphore。如果semaphore的内部计数器的值大于0,那么semaphore减少计数器的值并允许访问共享的资源。计数器的值大于0表示,有可以自由使用的资源,所以线程可以访问并使用它们。

package chapter3;

import java.util.concurrent.Semaphore;

public class PrintQueue2 {
	private final Semaphore semaphore;
	public PrintQueue2(){
		semaphore = new Semaphore(1);

	}
	public void printJob(Object document){

		try {
			semaphore.acquire();
			long duration = (long)(Math.random()*10);
			System.out.println(Thread.currentThread().getName()+"  PrintQueue   "+duration
					);
		} catch (InterruptedException e) {
			e.printStackTrace();

		}finally{
			semaphore.release();
		}
	}
}
package chapter3;

public class Job implements Runnable{
	private PrintQueue2 printQueue;
	public Job(PrintQueue2 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 chapter3;

public class Main {

	/**
	 * <p>
	 * </p>
	 * @author zhangjunshuai
	 * @date 2014-9-23 下午8:45:31
	 * @param args
	 */
	public static void main(String[] args) {
		PrintQueue2 printQueue = new PrintQueue2();
		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();
		}
	}

}

可修改Semaphores的公平性,在默认的情况下信号量的进入是不公平的。如果在初始化的第二个参数设定为true时,则会选择时间等待最久的一个进入。

参考:

并发网

老紫竹并发学习

时间: 2024-08-02 12:14:03

Java并发学习之十六——线程同步工具之信号量(Semaphores)的相关文章

Java并发学习之十九——线程同步工具之Phaser

本文是学习网络上的文章时的总结.感谢大家无私的分享. JDK 1.7 加入了一个新的工具Phaser.Phaser的在功能上与CountDownLatch有部分重合. 以下使用Phaser类来同步3个并发任务. 这3个任务会在3个不同的目录和它们的子目录中搜索扩展名是.log的文件. 这个任务被分成3个步骤: 1. 在指定的目录和子目录中获得文件扩展名为.log的文件列表. 2. 在操控台打印结果. 在步骤1和步骤2的结尾我们要检查列表是否为空. 假设为空.那么线程直接结束执行并从phaser类

Java并发学习之十八——线程同步工具之CyclicBarrier

本文是学习网络上的文章时的总结,感谢大家无私的分享. CyclicBarrier 类有一个整数初始值,此值表示将在同一点同步的线程数量.当其中一个线程到达确定点,它会调用await() 方法来等待其他线程.当线程调用这个方法,CyclicBarrier阻塞线程进入休眠直到其他线程到达.当最后一个线程调用CyclicBarrier 类的await() 方法,它唤醒所有等待的线程并继续执行它们的任务. 注意比较CountDownLatch和CyclicBarrier: 1.CountDownLatc

Java并发学习之十二——在同步的类里安排独立属性

本文是学习网络上的文章时的总结,感谢大家无私的分享. 当你使用synchronized关键字来保护代码块时,你必须通过一个对象的引用作为参数.通常,你将会使用this关键字来引用执行该方法的对象,但是你也可以使用其他对象引用.通常情况下,这些对象被创建只有这个目的.比如,你在一个类中有被多个线程共享的两个独立属性.你必须同步访问每个变量,如果有一个线程访问一个属性和另一个线程在同一时刻访问另一个属性,这是没有问题的. 当你使用synchronized关键字来保护代码块,你使用一个对象作为参数.J

Java并发学习之十——用线程工厂创建线程

本文是学习网络上的文章时的总结,感谢大家无私的分享. 1.工厂模式是最有用的设计模式.它是一个创造模式,还有他的目的是创建一个 或者几个类对象的对象.有了这个工厂,我们有这些优势集中创建对象: 更简单的改变了类的对象创建或者说创建这些对象的方式: 更简单的为了限制的资源限制了对象的创建. 更简单的生成创建对象的统计数据. 2.Java提供一个接口,ThreadFactory接口实现一个线程对象工厂 package chapter; import java.util.ArrayList; impo

Java并发学习之十四——使用Lock同步代码块

本文是学习网络上的文章时的总结,感谢大家无私的分享. Java提供另外的机制用来同步代码块.它比synchronized关键字更加强大.灵活.Lock 接口比synchronized关键字提供更多额外的功能.在使用Lock时需要注意的是要释放Lock锁. package chapter2; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; /* * 打印队列 */ pu

java系统学习(十) --------线程

线程的基本概念 进程以及使用环境 程序是计算机指令的集合,它以文件形式存储在磁盘上,而进程就是一个执行中的程序,每一个进程都有其独立的内存空间和系统资源.进程就是一个运行的程序,Windows操作系统是支持多进程的操作系统,即同一时间l可以执行多个程序,每个程序是在自己独立的内存空间内,使用自己被分配到的系统资源.其实,这种说法并不准确,一个CPU在某个时刻,实际上只能运行一个程序,即一个进程.所谓的支持多进程,其实就是CPU在非常快速的交替轮流执行多个程序,例如,利用Windows操作系统可以

Java并发编程的艺术(六)——线程间的通信

多条线程之间有时需要数据交互,下面介绍五种线程间数据交互的方式,他们的使用场景各有不同. 1. volatile.synchronized关键字 PS:关于volatile的详细介绍请移步至:Java并发编程的艺术(三)--volatile 1.1 如何实现通信? 这两种方式都采用了同步机制实现多条线程间的数据通信.与其说是"通信",倒不如说是"共享变量"来的恰当.当一个共享变量被volatile修饰 或 被同步块包裹后,他们的读写操作都会直接操作共享内存,从而各个

Java基础学习笔记十六 集合框架(二)

List List接口的特点: 它是一个元素存取有序的集合.例如,存元素的顺序是11.22.33.那么集合中,元素的存储就是按照11.22.33的顺序完成的. 它是一个带有索引的集合,通过索引就可以精确的操作集合中的元素(与数组的索引是一个道理). 集合中可以有重复的元素,通过元素的equals方法,来比较是否为重复的元素. List接口的常用子类有: ArrayList集合 LinkedList集合 List接口的特有方法(带索引的方法)1.增加元素方法 add(Object e):向集合末尾

java并发编程(十六)happen-before规则

转载请注明出处:http://blog.csdn.net/ns_code/article/details/17348313 happen-before规则介绍 Java语言中有一个"先行发生"(happen-before)的规则,它是Java内存模型中定义的两项操作之间的偏序关系,如果操作A先行发生于操作B,其意思就是说,在发生操作B之前,操作A产生的影响都能被操作B观察到,"影响"包括修改了内存中共享变量的值.发送了消息.调用了方法等,它与时间上的先后发生基本没有