同步器 java
除了基于每个Java对象具有的锁定位的通用同步外,您还可以使用Java中更复杂的同步器,例如:
- 信号量 –使用许可的概念表示一个位置中允许的最大线程数。 当使用值1时,其行为类似于同步,也称为二进制信号量。 但是,这里有很大的不同,您在信号量上获得许可,而不是锁定对象,它只是一个变量,用于在线程获得许可时进行计数,而在线程释放许可时进行计数。 您真正拥有的唯一东西是线程锁定,直到获得许可为止。 在下面的示例中,我们将3定义为允许的数量,因此在3 获得之后 ,4线程将等待释放,然后继续执行。
// Define the semaphore to control 3 permits.
// 3 Threads can acquire the mySemaphore
Semaphore mySemaphore = new Semaphore(3, true);
// 3 threads can execute this line of code. The 4 thread must wait for a release
mySemaphore.acquire();
// .. somewhere in the code a thread releases the mySemaphore,
// and now the next waiting thread can acquire
mySemaphore.release();
- CountDownLatch –用一个数字初始化该类(倒数),当达到0时,线程等待解除阻塞并遵循其方式。 (在等待之后 ,闩锁无法重复使用)
// Initializes a countdown starting from 3
CountDownLatch latch = new CountDownLatch(3);
// ... other threads are running...
// Some thread blocks and waits for the latch countdown
// to reach "0"
latch.await();
// ... code, methods, other objects... etc...
// ... at some place the OTHER threads do the countdown,
// decrementing the latch.. when it reachs 0
// the blocked thread with the "await()" follows its way
latch.countDown();
- CyclicBarrier –此类的行为与CountDownLatch相反。 在N await()之后 ,被阻塞的线程可以按照自己的方式进行。 (可以重用CyclicBarrier)
// 3 threads must await before can unblock
CyclicBarrier barrier = new CyclicBarrier(3);
// threads they block here until the 3 is reached
barrier.await();
// after 3 threads in await this code will run!
System.out.println("Thank you to the 3 friends who awaited for me!”);
- 移相器 –非常复杂的同步器,由CountDownLatch和CyclicBarrier混合而成,具有许多自定义选项。 如果您需要一个类似于2个以前的同步器的行为,但是它们还不够,那么您想深入研究一下这个同步器。 它的行为类似于CyclicBarrier,但是您可以注册一组线程并随时注销,以实现其他同步器无法实现的自定义级别。 考虑是否需要等待线程到达,然后才能继续或启动另一组任务。 在Oracle网站上有关此的更多信息:
http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Phaser.html
void runTasks(List<Runnable> tasks) {
// Initialize the phaser, "1" to register self
final Phaser phaser = new Phaser(1);
// create and start threads
for (final Runnable task : tasks) {
// register here
phaser.register();
new Thread() {
public void run() {
// await all creation
phaser.arriveAndAwaitAdvance();
task.run();
}
}.start();
}
// allow threads to start and deregister self
phaser.arriveAndDeregister();
}
- Exchanger –最好的解释来自Oracle文档本身: “一个同步点,线程可以在该同步点进行配对并在配对中交换元素 ”。 一个线程想将信息发送到另一个线程并阻塞等待发送数据,而在EXCHANGE中也接收另一个线程想发送的信息! 双方都会发生这种行为!
// Create the exchanger.
// We choose String as the data datatype
Exchanger<String> ex = new Exchanger<String>();
//
// .... Somewhere at Thread 1,
//
// I will block until I can send str1 to Thread 2, and receive a value too!
String str1 = "value to send from Thread 1 to Thread 2";
String valueReturnedFromThread2 = ex.exchange(str1);
//
// ... Somewhere at Thread 2,
//
// I will block until I can send str2 to Thread 1
// I will receive a value from Thread 1 too!
String str2 = "value to send to Thread 1 from Thread 2";
String valueReturnedFromThread1 = ex.exchange(str2);
翻译自: https://www.javacodegeeks.com/2013/05/five-advanced-java-synchronizers-you-probably-dont-know.html
同步器 java