1.CyclicBarrier(屏障)
CyclicBarrier类是通过设置屏障点来管理同步的,当所有参与的线程都到达指定屏障的时候,那么参与的所有线程就会全部 积蓄运行,具体测试代码如下:
public class CyclicBarrierTest { // 定义一个循环屏障 private CyclicBarrier cyclicBarrier; // 构造函数 //count为参与执行的线程数 //rn为所有线程到达屏障后需要做的行为 public CyclicBarrierTest(int count, Runnable rn) { this.cyclicBarrier = new CyclicBarrier(count, rn); } public void sayHello(String name, int time) { System.out.println("开始执行:" + name); try { Thread.sleep(time); this.cyclicBarrier.await(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (BrokenBarrierException e) { e.printStackTrace(); } System.out.println("结束执行:" + name); } public static void main(String[] args) { final CyclicBarrierTest cbt = new CyclicBarrierTest(3, new Runnable() { @Override public void run() { System.out.println("执行数量的线程完成后执行"); } }); // 创建三个测试线程 Thread t1 = new Thread(new Runnable() { @Override public void run() { cbt.sayHello("T1", 500); } }); Thread t2 = new Thread(new Runnable() { @Override public void run() { cbt.sayHello("T2", 1000); } }); Thread t3 = new Thread(new Runnable() { @Override public void run() { cbt.sayHello("T3", 2000); } }); //启动三个线程 t1.start(); t2.start(); t3.start(); } }
上述代码的运行结果,应该是:
开始执行:T1
开始执行:T2
开始执行:T3
执行数量的线程完成后执行
结束执行:T1
结束执行:T2
结束执行:T3
2.CountDownLatch(计数)
CountDownLatch类是通过线程计数来实现同步的,也就是有一个计数器,在计数器未到0之前所有相关线程在指定位置都需要阻 塞,直到计数器为0的时候,所有相关线程停止阻塞,继续向下执行。需要注意的是,该同步器不能被复用,并且可以由外部事件触发。
public class CountDownLatchTest { private CountDownLatch countDownLatch = null; //构造函数,创建倒计时同步器 //count为倒计时数 public CountDownLatchTest(int count){ this.countDownLatch = new CountDownLatch(count); } //递减计数器 public void countDown(){ this.countDownLatch.countDown(); System.out.println("count:" + this.countDownLatch.getCount()); } public void sayHello(String name, int time) { System.out.println("开始执行:" + name); try { Thread.sleep(time); this.countDownLatch.await(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("结束执行:" + name); } public static void main(String[] args) throws InterruptedException { final CountDownLatchTest cdl = new CountDownLatchTest(3); // 创建三个测试线程 Thread t1 = new Thread(new Runnable() { @Override public void run() { cdl.sayHello("T1", 50); } }); Thread t2 = new Thread(new Runnable() { @Override public void run() { cdl.sayHello("T2", 50); } }); Thread t3 = new Thread(new Runnable() { @Override public void run() { cdl.sayHello("T3", 50); } }); //启动测试线程 t1.start(); t2.start(); t3.start(); Thread.sleep(2000); //逐步递减 cdl.countDown(); Thread.sleep(1000); cdl.countDown(); Thread.sleep(1000); cdl.countDown(); Thread.sleep(1000); } }
上述代码由于线程运行的不确定性,每次的运行结果都不一样,但原则不变,例如:
开始执行:T1
开始执行:T2
开始执行:T3
count:2
count:1
count:0
结束执行:T2
结束执行:T3
结束执行:T1
3.Exchanger(交换)
Exchanger类用于不同线程间交换数据,并且交换过程是线程安全的,通过设置一个同步点来实现,具体代码如下:
public class ExchangerTest { private Exchanger<String> exchanger; public ExchangerTest(){ this.exchanger = new Exchanger<String>(); } public void method1(String name){ System.out.println("执行Mehtod1"); //Thread.sleep(1000);\ String ss = name + "发送数据:123123" ; try { ss = this.exchanger.exchange(ss); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("结束Mehtod1"); } public void method2(String name){ System.out.println("执行Mehtod2"); String ss = "123"; try { ss = this.exchanger.exchange(ss); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("Mehotd2收到:" + ss); System.out.println("结束Mehtod2"); } public static void main(String[] args) { final ExchangerTest et = new ExchangerTest(); // 创建三个测试线程 Thread t1 = new Thread(new Runnable() { @Override public void run() { et.method1("T1"); } }); Thread t2 = new Thread(new Runnable() { @Override public void run() { et.method2("T2"); } }); //启动测试线程 t2.start(); t1.start(); } }
上述代码的运行结果,应该是:
执行Mehtod2
执行Mehtod1
结束Mehtod1
Mehotd2收到:T1发送数据:123123
结束Mehtod2
4.SynchronousQueue(同步队列)
该同步器是阻塞队列的一种,虽然称之为队列,但是该“队列”没有长度。使用该队列的规则是:没有存不允许取,没有取不允许存。该队列的方法很多,但一般使用较多的是put和take方法,因为这两个方法实现了阻塞方式的存取,代码如下:
public class SynchronousQueueTest { private SynchronousQueue<String> synchronousQueue; public SynchronousQueueTest(){ //构造函数内的参数表示是否采取公平策略 //即优先照顾等待时间比较长的线程 //使用公平策略会影响性能 this.synchronousQueue = new SynchronousQueue<String>(false); } public void put(String data){ try { System.out.println("等待放入:" + data); this.synchronousQueue.put(data); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public String take(){ String data = null; try { data = this.synchronousQueue.take(); System.out.println("提取了:" + data); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } return data; } public static void main(String[] args) { final SynchronousQueueTest sqt = new SynchronousQueueTest(); // 创建三个测试线程 Thread t1 = new Thread(new Runnable() { @Override public void run() { sqt.put("111111"); try { Thread.sleep(4000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } sqt.put("222222"); } }); Thread t2 = new Thread(new Runnable() { @Override public void run() { sqt.take(); sqt.take(); } }); //启动测试线程 t1.start(); t2.start(); } }
上述代码的运行结果,应该是:
等待放入:111111
提取了:111111
等待放入:222222
提取了:222222
5.Semaphore(信号量)
Semaphore类通过类似许可证的方式对同步进行管理,简单的来说,许可证的数目是一定的,想要访问,必须要获得许可证,若许可证已经用完,那么必须等待其他占用许可证的线程归还许可证后,方可得到许可从而继续执行。具体代码如下:
public class SemaphoreTest { private Semaphore semaphore; //构造函数用于创建一个信号量同步器 //count为许可个数 //fair表示是否采用公平策略 public SemaphoreTest(int count,boolean fair){ this.semaphore = new Semaphore(count,fair); } public void sayHello(String name){ try { this.semaphore.acquire(); System.out.println(name + "得到许可"); Thread.sleep(5000); this.semaphore.release(); System.out.println(name + "释放许可"); } catch (InterruptedException e) { e.printStackTrace(); } } public static void main(String[] args) { final SemaphoreTest st = new SemaphoreTest(3,false); // 创建测试线程 Thread t1 = new Thread(new Runnable() { @Override public void run() { st.sayHello("T1"); } }); Thread t2 = new Thread(new Runnable() { @Override public void run() { st.sayHello("T2"); } }); Thread t3 = new Thread(new Runnable() { @Override public void run() { st.sayHello("T3"); } }); Thread t4 = new Thread(new Runnable() { @Override public void run() { st.sayHello("T4"); } }); Thread t5 = new Thread(new Runnable() { @Override public void run() { st.sayHello("T5"); } }); t1.start(); t2.start(); t3.start(); t4.start(); t5.start(); } }
上述代码由于线程运行的不确定性,每次的运行结果都不一样,但原则不变,例如:
T1得到许可
T2得到许可
T4得到许可
T2释放许可
T4释放许可
T3得到许可
T1释放许可
T5得到许可
T3释放许可
T5释放许可
相关推荐
根据提供的信息,我们可以深入探讨Java线程同步以及代码示例中的关键知识点。 ### Java线程同步实例:哲学家就餐问题 #### 1. 哲学家就餐问题简介 哲学家就餐问题是多线程编程中一个经典的同步问题。该问题描述为...
总结一下,Java线程同步的关键点: 1. **线程同步是为了解决共享资源的并发访问问题,防止数据不一致和冲突。** 2. **同步意味着线程排队,依次访问共享资源,而不是同时访问。** 3. **只有共享变量(可变状态)才...
在“操作系统实验 多线程同步与互斥 java编写 有界面”的实验中,可能需要设计一个图形用户界面(GUI),通过按钮或事件触发线程的创建和同步操作,直观地展示线程间的交互和同步效果。例如,可以模拟银行账户转账,...
### Java分布式应用学习笔记05多线程下的并发同步器 #### 1. 前言 在现代软件开发中,特别是在分布式系统和高性能计算领域,有效地管理多线程之间的协同工作至关重要。Java语言提供了丰富的工具和API来帮助开发者...
Java线程同步是多线程编程中的一个重要概念,它用于解决在并发环境下多个线程对共享资源的访问问题,以防止数据的不一致性。在Java中,线程同步的机制主要包括锁、同步块、同步方法、volatile关键字以及线程通信(如...
总结来说,Java线程同步是通过监视器机制实现的,包括互斥和协作两种方式。互斥确保了同一时间只有一个线程访问共享数据,而协作则允许线程通过`wait()`和`notify()`方法进行通信和协调,以完成特定的任务。理解并...
在Java中,线程同步是保证多线程安全...上述Java线程同步例子中涉及到的代码虽然是片段,但涵盖了线程同步处理的多个重要方面,帮助我们理解和使用Java线程同步机制,以及在设计和实现多线程应用程序时的实践和技巧。
本实例65着重讲解了Java线程同步的实现方法,帮助开发者理解和掌握如何在并发环境中保证代码的正确执行。 首先,我们要了解什么是线程。线程是程序中的执行流,每个线程都有自己的程序计数器、栈、局部变量和常量,...
Java多线程下载器是一种利用Java编程语言实现的高效文件下载工具,它通过将大文件分割成多个部分并同时下载,显著提高了下载速度。在Java中实现多线程下载器涉及许多关键概念和技术,包括线程、并发控制、网络I/O...
本文将深入探讨Java多线程中的关键知识点,包括创建线程、主线程、线程优先级、线程组、线程同步以及线程间的通信。 1. **创建线程** 在Java中,可以通过两种方式创建线程:继承`Thread`类或实现`Runnable`接口。...
本文将深入解析Java线程的相关知识点,包括线程的定义、创建、状态管理、线程同步和安全问题。 1. **线程定义** 在Java中,线程是进程中的单一顺序控制流,是程序执行的基本单元。线程在进程的上下文中运行,共享...
Java线程同步是一种控制多个线程访问共享资源的方式,确保数据的一致性和完整性。在这个例子中,我们将讨论如何使用`synchronized`关键字实现线程同步,以及它的工作原理。 首先,我们有两个类`ThreadDemo`和`...
Java线程同步是一种确保多个线程在访问共享资源时能够有序执行的技术,避免了数据的不一致性和竞态条件。在给定的示例中,通过两种方式展示了线程同步:synchronized方法和synchronized代码块。 首先,我们来看同步...
通过学习这个Java线程使用教程,你将能够熟练地在多线程环境中编写高效、安全的Java程序,理解线程同步、通信、线程池以及并发工具类的使用。阅读提供的"Java线程.pdf"和"说明.txt"文件将帮助你更深入地掌握这些知识...
Java线程有10个优先级(MIN_PRIORITY, NORM_PRIORITY, MAX_PRIORITY),默认优先级是NORM_PRIORITY。但是,线程优先级并不保证绝对的执行顺序,操作系统调度策略可能影响实际执行顺序。 7. join()方法: 一个线程...
Java线程:概念与原理 Java线程:创建与启动 Java线程:线程栈模型与线程的变量 Java线程:线程状态的转换 Java线程:线程的同步与锁 Java线程:线程的交互 ...Java线程:新特征-障碍器 Java线程:大总结
3. **并发控制(Concurrency Control)**:为了协调多个线程的下载,可能需要使用同步机制,如`synchronized`关键字、`java.util.concurrent`包中的锁或条件变量。例如,可能需要确保所有线程在写入文件时不会相互...
7. **线程同步**:Java提供了多种同步机制,包括synchronized关键字(锁定对象或代码块)、Lock接口(如ReentrantLock)以及volatile关键字,以确保多线程环境下数据的一致性和可见性。 8. **锁**:Java中的锁包括...
#### 四、Java线程同步机制 **4.1 synchronized关键字** `synchronized`关键字用于保证线程间的可见性和有序性。它可以修饰方法或者代码块,确保任何时候只有一个线程可以访问被锁定的对象或代码块。 ```java ...