Semaphore(int permits)
or Semaphore(int permits, boolean fair)
) always passes the number of threads that the semaphore will allow to simultaneously use the specified resource.int permits
, when a thread enters a given block of code, the counter value decreases by one, when the stream leaves it, it increases. If the counter value is zero, then the current flow is blocked until someone leaves the block (as an example of life with permits = 1
, you can bring a queue to the office in the clinic: when the patient leaves the office, the lamp flashes, and the next patient enters ). import java.util.concurrent.Semaphore; public class Parking { // - true, - false private static final boolean[] PARKING_PLACES = new boolean[5]; // "", //aquire() private static final Semaphore SEMAPHORE = new Semaphore(5, true); public static void main(String[] args) throws InterruptedException { for (int i = 1; i <= 7; i++) { new Thread(new Car(i)).start(); Thread.sleep(400); } } public static class Car implements Runnable { private int carNumber; public Car(int carNumber) { this.carNumber = carNumber; } @Override public void run() { System.out.printf(" â„–%d .\n", carNumber); try { //acquire() , // , , // SEMAPHORE.acquire(); int parkingNumber = -1; // synchronized (PARKING_PLACES){ for (int i = 0; i < 5; i++) if (!PARKING_PLACES[i]) { // PARKING_PLACES[i] = true; // parkingNumber = i; // , System.out.printf(" â„–%d %d.\n", carNumber, i); break; } } Thread.sleep(5000); // , synchronized (PARKING_PLACES) { PARKING_PLACES[parkingNumber] = false;// } //release(), , SEMAPHORE.release(); System.out.printf(" â„–%d .\n", carNumber); } catch (InterruptedException e) { } } } }
CountDownLatch(int count)
) constructor must pass the number of operations that must be performed in order for the lock to “release” the blocked threads. import java.util.concurrent.CountDownLatch; public class Race { // CountDownLatch 8 "" private static final CountDownLatch START = new CountDownLatch(8); // private static final int trackLength = 500000; public static void main(String[] args) throws InterruptedException { for (int i = 1; i <= 5; i++) { new Thread(new Car(i, (int) (Math.random() * 100 + 50))).start(); Thread.sleep(1000); } while (START.getCount() > 3) //, Thread.sleep(100); // . , 100ms Thread.sleep(1000); System.out.println(" !"); START.countDown();// , 1 Thread.sleep(1000); System.out.println("!"); START.countDown();// , 1 Thread.sleep(1000); System.out.println("!"); START.countDown();// , 1 // , // } public static class Car implements Runnable { private int carNumber; private int carSpeed;//, public Car(int carNumber, int carSpeed) { this.carNumber = carNumber; this.carSpeed = carSpeed; } @Override public void run() { try { System.out.printf(" №%d .\n", carNumber); // - // 1 START.countDown(); // await() , , , // CountDownLatch 0 START.await(); Thread.sleep(trackLength / carSpeed);// System.out.printf(" №%d !\n", carNumber); } catch (InterruptedException e) { } } } }
CyclicBarrier(int parties)
and CyclicBarrier(int parties, Runnable barrierAction)
) must transmit the number of parties that must “meet”, and, optionally, the action that should occur when the parties meet, but before "Released."join()
method, which “collects” threads only after they have been executed. import java.util.concurrent.CyclicBarrier; public class Ferry { private static final CyclicBarrier BARRIER = new CyclicBarrier(3, new FerryBoat()); // , , // . , . public static void main(String[] args) throws InterruptedException { for (int i = 0; i < 9; i++) { new Thread(new Car(i)).start(); Thread.sleep(400); } } //, public static class FerryBoat implements Runnable { @Override public void run() { try { Thread.sleep(500); System.out.println(" !"); } catch (InterruptedException e) { } } } //, public static class Car implements Runnable { private int carNumber; public Car(int carNumber) { this.carNumber = carNumber; } @Override public void run() { try { System.out.printf(" №%d .\n", carNumber); // , await() // , BARRIER.await(); System.out.printf(" №%d .\n", carNumber); } catch (Exception e) { } } } }
await()
method, the barrier action is triggered and the ferry forwards three cars from the accumulated ones. After this, a new cycle begins.exchange()
method on the exchange()
blocked and another thread is waiting. When another thread calls the same method, objects will be exchanged: each of them will receive the argument of the other in the exchange()
method. It is worth noting that the exchanger supports the transfer of null
values. This makes it possible to use it to transfer an object in one direction, or simply as a synchronization point for two streams. import java.util.concurrent.Exchanger; public class Delivery { // , String private static final Exchanger<String> EXCHANGER = new Exchanger<>(); public static void main(String[] args) throws InterruptedException { String[] p1 = new String[]{"{ A->D}", "{ A->C}"};// 1- String[] p2 = new String[]{"{ B->C}", "{ B->D}"};// 2- new Thread(new Truck(1, "A", "D", p1)).start();// 1- D Thread.sleep(100); new Thread(new Truck(2, "B", "C", p2)).start();// 2- } public static class Truck implements Runnable { private int number; private String dep; private String dest; private String[] parcels; public Truck(int number, String departure, String destination, String[] parcels) { this.number = number; this.dep = departure; this.dest = destination; this.parcels = parcels; } @Override public void run() { try { System.out.printf(" â„–%d : %s %s.\n", number, parcels[0], parcels[1]); System.out.printf(" â„–%d %s %s.\n", number, dep, dest); Thread.sleep(1000 + (long) Math.random() * 5000); System.out.printf(" â„–%d .\n", number); parcels[1] = EXCHANGER.exchange(parcels[1]);// exchange() // exchange(), System.out.printf(" â„–%d %s.\n", number, dest); Thread.sleep(1000 + (long) Math.random() * 5000); System.out.printf(" â„–%d %s : %s %s.\n", number, dest, parcels[0], parcels[1]); } catch (InterruptedException e) { } } } }
Phaser() Phaser(int parties)
CyclicBarrier.await()
. Returns the current phase number; import java.util.ArrayList; import java.util.concurrent.Phaser; public class Bus { private static final Phaser PHASER = new Phaser(1);// // 0 6 - , 1 - 5 public static void main(String[] args) throws InterruptedException { ArrayList<Passenger> passengers = new ArrayList<>(); for (int i = 1; i < 5; i++) { // if ((int) (Math.random() * 2) > 0) passengers.add(new Passenger(i, i + 1));// if ((int) (Math.random() * 2) > 0) passengers.add(new Passenger(i, 5)); // } for (int i = 0; i < 7; i++) { switch (i) { case 0: System.out.println(" ."); PHASER.arrive();// 0 1 - break; case 6: System.out.println(" ."); PHASER.arriveAndDeregister();// , break; default: int currentBusStop = PHASER.getPhase(); System.out.println(" â„– " + currentBusStop); for (Passenger p : passengers) //, if (p.departure == currentBusStop) { PHASER.register();// , p.start(); // } PHASER.arriveAndAwaitAdvance();// } } } public static class Passenger extends Thread { private int departure; private int destination; public Passenger(int departure, int destination) { this.departure = departure; this.destination = destination; System.out.println(this + " â„– " + this.departure); } @Override public void run() { try { System.out.println(this + " ."); while (PHASER.getPhase() < destination) // () PHASER.arriveAndAwaitAdvance(); // Thread.sleep(1); System.out.println(this + " ."); PHASER.arriveAndDeregister(); // } catch (InterruptedException e) { } } @Override public String toString() { return "{" + departure + " -> " + destination + '}'; } } }
import java.util.concurrent.Phaser; public class NewRace { private static final Phaser START = new Phaser(8); private static final int trackLength = 500000; public static void main(String[] args) throws InterruptedException { for (int i = 1; i <= 5; i++) { new Thread(new Car(i, (int) (Math.random() * 100 + 50))).start(); Thread.sleep(100); } while (START.getRegisteredParties() > 3) //, Thread.sleep(100); // . , 100ms Thread.sleep(100); System.out.println(" !"); START.arriveAndDeregister(); Thread.sleep(100); System.out.println("!"); START.arriveAndDeregister(); Thread.sleep(100); System.out.println("!"); START.arriveAndDeregister(); } public static class Car implements Runnable { private int carNumber; private int carSpeed; public Car(int carNumber, int carSpeed) { this.carNumber = carNumber; this.carSpeed = carSpeed; } @Override public void run() { try { System.out.printf(" â„–%d .\n", carNumber); START.arriveAndDeregister(); START.awaitAdvance(0); Thread.sleep(trackLength / carSpeed); System.out.printf(" â„–%d !\n", carNumber); } catch (InterruptedException e) { } } } }
Source: https://habr.com/ru/post/277669/
All Articles