`
Lucas_
  • 浏览: 4789 次
  • 性别: Icon_minigender_1
社区版块
存档分类
最新评论

Java并发编程:同步工具类

 
阅读更多

Java并发编程:同步工具类

1.Semaphore类  一个计数信号量,通常用于限制可以访问某些资源(物理或逻辑的)的线程数目。功能和锁有点类似,它一般用于控制对某组资源的访问权限。

          acquire()用来获取一个许可,若无许可能够获得,则会一直等待,直到获得许可。

          release()用来释放许可。注意,在释放许可之前,必须先获获得许可。

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;

public class SemaphoreTest {
	public static void main(String[] args) {
		ExecutorService service = Executors.newCachedThreadPool();
		final Semaphore sp = new Semaphore(3);

		for (int i = 0; i < 10; i++) {
			Runnable runnable = new Runnable() {
				public void run() {
					try {
						sp.acquire();
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					System.out.println("线程 " + Thread.currentThread().getName()
							+ " 进入,当前已有 " + (3 - sp.availablePermits())
							+ "个线程并发");

					try {
						Thread.sleep((long) Math.random() * 1000);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					System.out.println("线程 " + Thread.currentThread().getName()
							+ "即将离开");
					sp.release();

					System.out.println("线程 " + Thread.currentThread().getName()
							+ " 已离开,当前已有" + (3 - sp.availablePermits())
							+ "个线程并发");
				}
			};
			service.execute(runnable);
		}
	}

}

 2.CyclicBarrier类一个同步辅助类,它允许一组线程互相等待,直到到达某个公共屏障点。

一组线程等待至某个状态之后再全部同时执行,例如班级出外郊游,当所有人到齐后才出发到下一个目的地。

/*
 		集齐够了所有线程再进行下一步工作
 */
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class CyclicBarrierTest {

	public static void main(String[] args) {
		ExecutorService service = Executors.newCachedThreadPool();
		final CyclicBarrier cb = new CyclicBarrier(3);
		for (int i = 0; i < 3; i++) {
			Runnable runnable = new Runnable() {
				public void run() {
					try {
						Thread.sleep((long) (Math.random() * 10000));
						System.out.println("线程"
								+ Thread.currentThread().getName()
								+ " 即将到达集合地点1,当前已有 "
								+ (cb.getNumberWaiting() + 1)
								+ "个已经到达,"
								+ ((cb.getNumberWaiting() == 2) ? " 全员都到齐了,出发!"
										: "正在等候"));
						cb.await();

						Thread.sleep((long) (Math.random() * 10000));
						System.out.println("线程"
								+ Thread.currentThread().getName()
								+ " 即将到达集合地点2,当前已有 "
								+ (cb.getNumberWaiting() + 1)
								+ "个已经到达,"
								+ ((cb.getNumberWaiting() == 2) ? "全员都到齐了,出发!"
										: "正在等候"));
						cb.await();
						Thread.sleep((long) (Math.random() * 10000));
						System.out.println("线程"
								+ Thread.currentThread().getName()
								+ " 即将到达集合地点3,当前已有 "
								+ (cb.getNumberWaiting() + 1)
								+ "个已经到达,"
								+ ((cb.getNumberWaiting() == 2) ? "全员都到齐了,返程!"
										: "正在等候"));
						cb.await();
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
			};
			service.execute(runnable);
		}
		service.shutdown();
	}
}

 3.CountDownLatch类一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待。

CountDownLatch 使用一个计数器来实现,它初始化为一个正,用来表示需要等待的活动事件数。countDown 方法使计数器减一,表示一个事件已经发生了,而await方法等待计数器达到零,此时表示所有需要等待的事件都已发生,只有当计数器到达零时,锁才会开起。如果计数器的初始值不为零,await会一直阻塞直到计数器为零,或者是等待线程中断或超时。

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class CountdownLatchTest {

	public static void main(String[] args) {
		ExecutorService service = Executors.newCachedThreadPool();
		final CountDownLatch cdOrder = new CountDownLatch(1); // 裁判吹一声口哨
																// 将计数1初始化做一个开/关锁存器,调用countDown()的线程打开
		final CountDownLatch cdAnswer = new CountDownLatch(3); // 三个运动员参加比赛
		for (int i = 0; i < 3; i++) {
			Runnable runnable = new Runnable() {
				public void run() {
					try {
						System.out.println("运动员"
								+ Thread.currentThread().getName()
								+ "正准备接受命令...");
						cdOrder.await();
						System.out.println("运动员"
								+ Thread.currentThread().getName() + "已接受命令");
						Thread.sleep((long) (Math.random() * 10000));
						System.out.println("运动员"
								+ Thread.currentThread().getName()
								+ "完成比赛,回应命令处理结果");
						cdAnswer.countDown();
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
			};
			service.execute(runnable);
		}
		try {
			Thread.sleep((long) (Math.random() * 10000));

			System.out.println("裁判" + Thread.currentThread().getName()
					+ "即将发布命令");
			cdOrder.countDown();
			System.out.println("裁判" + Thread.currentThread().getName()
					+ "已发送开始命令,正在等待比赛结果....");
			cdAnswer.await();
			System.out.println("裁判" + Thread.currentThread().getName()
					+ "已收到所有响应结果,宣布结果");
		} catch (Exception e) {
			e.printStackTrace();
		}
		service.shutdown();

	}
}

 4.Exchanger类   两个线程可以交换对象的同步点。每个线程都在进入 exchange 方法时给出某个对象,相互接受对方准备的对象。

import java.util.concurrent.Exchanger;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ExchangerTest {

	public static void main(String[] args) {
		ExecutorService service = Executors.newCachedThreadPool();
		final Exchanger exchanger = new Exchanger();

		service.execute(new Runnable() {
			public void run() {
				try {
					Thread.sleep((long) (Math.random() * 10000));
					String data1 = "Drug";
					System.out.println("线程" + Thread.currentThread().getName()
							+ "正在把 " + data1 + " 换出去");
					String data2 = (String) exchanger.exchange(data1);
					System.out.println("线程" + Thread.currentThread().getName()
							+ "换回的东西为 " + data2);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
		service.execute(new Runnable() {
			public void run() {
				try {
					Thread.sleep((long) (Math.random() * 10000));
					String data1 = "Money";
					System.out.println("线程" + Thread.currentThread().getName()
							+ "正在把 " + data1 + " 换出去");
					String data2 = (String) exchanger.exchange(data1);
					System.out.println("线程" + Thread.currentThread().getName()
							+ "换回的东西为" + data2);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}
}

 

 

分享到:
评论

相关推荐

    java并发编程:juc、aqs

    Java 并发编程中的 JUC(java.util.concurrent)库以及其核心组件 AQS(AbstractQueuedSynchronizer)在构建高性能、可伸缩性的多线程应用方面具有重要的地位。 AQS 是 JUC 中的核心组件,它提供了一个框架,让...

    Java并发编程实战

    5.5 同步工具类 5.5.1 闭锁 5.5.2 FutureTask 5.5.3 信号量 5.5.4 栅栏 5.6 构建高效且可伸缩的结果缓存 第二部分 结构化并发应用程序 第6章 任务执行 6.1 在线程中执行任务 6.1.1 串行地执行任务 6.1.2 ...

    JAVA并发编程实践 .pdf

    如何提高单线程子系统的响应性,如何确保并发程序执行预期任务,如何提高并发代码的性能和可伸缩性等内容,最后介绍了一些高级主题,如显式锁、原子变量、非阻塞算法以及如何开发自定义的同步工具类。 《Java并发编程...

    Java并发编程:同步容器

    为了方便编写出线程安全的程序,Java里面提供了一些线程安全类和并发工具,比如:同步容器、并发容器、阻塞队列、Synchronizer(比如CountDownLatch)。我们来讨论下同步容器。  一.为什么会出现同步容器?  在...

    Java并发编程实战.rar

    《Java并发编程实战》是一本完美的Java并发参考手册。书中从并发性和线程安全性的基本概念出发,介绍了如何使用类库提供的基本并发构建块,用于避免并发危险、构造线程安全的类及验证线程安全的规则,如何将小的线程...

    java并发编程

    本书全面介绍了如何使用Java 2平台进行并发编程,较上一版新增和扩展的内容包括:, ·存储模型 ·取消 ·可移植的并行编程 ·实现并发控制的工具类, Java平台提供了一套广泛而功能强大的api,工具和技术。...

    Java 并发编程实战

    5.5 同步工具类 5.5.1 闭锁 5.5.2 FutureTask 5.5.3 信号量 5.5.4 栅栏 5.6 构建高效且可伸缩的结果缓存 第二部分 结构化并发应用程序 第6章 任务执行 6.1 在线程中执行任务 6.1.1 串行地执行任务 6.1.2 ...

    Java并发编程实践 PDF 高清版

    本书的读者是那些具有一定Java编程经验的程序员、希望了解Java SE 5,6在线程技术上的改进和新特性的程序员,以及Java和并发编程的爱好者。 目录 代码清单 序 第1章 介绍 1.1 并发的(非常)简短历史 1.2 线程的...

    JAVA并发编程实践 带书签

    如何提高单线程子系统的响应性,如何确保并发程序执行预期任务,如何提高并发代码的性能和可伸缩性等内容,最后介绍了一些高级主题,如显式锁、原子变量、非阻塞算法以及如何开发自定义的同步工具类。

    Java并发编程实战(华章专业开发者书库).mobi

    如何提高单线程子系统的响应性,如何确保并发程序执行预期任务,如何提高并发代码的性能和可伸缩性等内容,最后介绍了一些高级主题,如显式锁、原子变量、非阻塞算法以及如何开发自定义的同步工具类。 本书适合Java...

    java并发编程实战相关书籍

    如何提高单线程子系统的响应性,如何确保并发程序执行预期任务,如何提高并发代码的性能和可伸缩性等内容,最后介绍了一些高级主题,如显式锁、原子变量、非阻塞算法以及如何开发自定义的同步工具类

    龙果 java并发编程原理实战

    龙果 java并发编程原理实战 第2节理解多线程与并发的之间的联系与区别 [免费观看] 00:11:59分钟 | 第3节解析多线程与多进程的联系以及上下文切换所导致资源浪费问题 [免费观看] 00:13:03分钟 | 第4节学习并发的四...

    Java 并发编程实战(中文+高清版).zip

    如何提高单线程子系统的响应性,如何确保并发程序执行预期任务,如何提高并发代码的性能和可伸缩性等内容,最后介绍了一些高级主题,如显式锁、原子变量、非阻塞算法以及如何开发自定义的同步工具类。

    Java并发编程实践

    《Java并发编程实战》深入浅出地介绍了Java线程和并发,是一本完美的Java并发参考手册。书中从并发性和线程安全性的基本概念出发,介绍了如何使用类库提供的基本并发构建块,用于避免并发危险、构造线程安全的类及...

    Java并发编程实战.pdf

    如何提高单线程子系统的响应性,如何确保并发程序执行预期任务,如何提高并发代码的性能和可伸缩性等内容,最后介绍了一些高级主题,如显式锁、原子变量、非阻塞算法以及如何开发自定义的同步工具类。

    Java并发编程基础.pdf

    Java并发编程基础主要包括以下几个核心方面: 线程与线程状态:理解Java中线程的基本概念,包括线程的创建、启动、暂停、恢复和终止。熟悉线程的生命周期及其不同状态,如新建、就绪、运行、阻塞和死亡。 线程同步...

    java编发编程:JUC综合讲解

    Java 并发编程在现代软件开发中占据重要地位,尤其是在多核处理器的时代。JUC(java.util.concurrent)库是 Java 标准库的一部分,提供了丰富的多线程并发工具,旨在帮助开发者编写高性能、高可伸缩性的并发程序。...

    《Java并发编程实战》

    如何提高单线程子系统的响应性,如何确保并发程序执行预期任务,如何提高并发代码的性能和可伸缩性等内容,最后介绍了一些高级主题,如显式锁、原子变量、非阻塞算法以及如何开发自定义的同步工具类。 《Java并发编程...

    Java并发编程原理与实战

    并发工具类CountDownLatch详解.mp4 并发工具类CyclicBarrier 详解.mp4 并发工具类Semaphore详解.mp4 并发工具类Exchanger详解.mp4 CountDownLatch,CyclicBarrier,Semaphore源码解析.mp4 提前完成任务之FutureTask...

Global site tag (gtag.js) - Google Analytics