предисловие
Когда я раньше изучал многопоточность, я не изучал класс инструмента синхронизации (вспомогательный класс) потоков. ps: В то время я думал, что это пока бесполезно.Я думал, что это очень продвинутый уровень знаний, и я проигнорировал его..
Несколько дней назад друг прислал относительно хорошую статью о семафоре, а затем, когда я просматривал блог, я обнаружил, что интервью все еще будет проверено, что по-прежнему является очень важным моментом знаний. Так что потребовалось некоторое время, чтобы выяснить это.
Java дает намТри класса инструментов синхронизации:
- CountDownLatch (защелка)
- циклическийбарьер
- Семафор (семафор)
На самом деле, эти инструменты просто умеютУлучшенный контроль над проблемами связи между потоками~
1. Защелка обратного отсчета
1.1 Введение в CountDownLatch
- A synchronization aid that allows one or more threads to wait until a set of operations being performed in other threads completes.
Проще говоря: CountDownLatch — синхронный вспомогательный класс,Разрешить одному или нескольким потокам ждать вечно,до того какдругой потокЗаканчиватьих эксплуатация.
На самом деле есть два часто используемых API:await()
иcountDown()
Инструкции по применению:
- count инициализирует CountDownLatch, а затем поток, который должен ждать, вызывает метод await. Метод await будет блокироваться до тех пор, пока count=0. После того, как другие потоки завершат свои операции, вызовите
countDown()
Уменьшите значение счетчика на 1.Когда count уменьшится до 0, все ожидающие потоки будут освобождены. - Другими словами, черезпеременная count для управления ожиданием,еслизначение счетчика равно 0(Задачи других потоков завершены), то выполнение может продолжаться.
1.2CountDownLatch Пример
Пример: 3y сейчас работает стажером, а другие сотрудники еще не закончили работу, 3y стесняется уйти первым, а когда все остальные сотрудники уйдут, 3y уйдет.
import java.util.concurrent.CountDownLatch;
public class Test {
public static void main(String[] args) {
final CountDownLatch countDownLatch = new CountDownLatch(5);
System.out.println("现在6点下班了.....");
// 3y线程启动
new Thread(new Runnable() {
@Override
public void run() {
try {
// 这里调用的是await()不是wait()
countDownLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("...其他的5个员工走光了,3y终于可以走了");
}
}).start();
// 其他员工线程启动
for (int i = 0; i < 5; i++) {
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("员工xxxx下班了");
countDownLatch.countDown();
}
}).start();
}
}
}
Выходной результат:
Напишем другой пример: 3y теперь отвечает за функцию модуля склада, но возможности слишком плохие, и запись очень медленная.Другим сотрудникам нужно подождать 3 года, прежде чем они смогут продолжить писать.
import java.util.concurrent.CountDownLatch;
public class Test {
public static void main(String[] args) {
final CountDownLatch countDownLatch = new CountDownLatch(1);
// 3y线程启动
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("3y终于写完了");
countDownLatch.countDown();
}
}).start();
// 其他员工线程启动
for (int i = 0; i < 5; i++) {
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("其他员工需要等待3y");
try {
countDownLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("3y终于写完了,其他员工可以开始了!");
}
}).start();
}
}
}
Выходной результат:
Использованная литература:
2. Циклический барьер
2.1 Введение в CyclicBarrier
- A synchronization aid that allows a set of threads to all wait for each other to reach a common barrier point. CyclicBarriers are useful in programs involving a fixed sized party of threads that must occasionally wait for each other. The barrier is called cyclic because it can be re-used after the waiting threads are released.
Вкратце: CyclicBarrier позволяет группе потоков ждать друг друга, покадобраться до общественного барьера. Он называется циклическим, потому что, когда все ожидающие потоки освобождаются, CyclicBarrier можетповторно использованный(В отличие от CountDownlatch не многоразовая)
Инструкции по применению:
- CountDownLatch фокусируется надождитесь завершения других потоков, CyclicBarrier фокусируется на: когда потокдостичь состоянияПосле этого сделайте паузу, чтобы дождаться других потоков,После достижения всех ниток, продолжить выполнение.
2.2 Пример циклического барьера
Пример: 3y и его девушка договорились о встрече, чтобы поужинать в Гуанчжоу вечером в Шанхае.Поскольку 3y и 3y подруга живут в разных местах, их естественный путь различен. Поэтому они согласились остановиться на станции метро Tiyu West Road.собирать, договорились подождатьпри встрече друг с другомОн сделал круг друзей.
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
public class Test {
public static void main(String[] args) {
final CyclicBarrier CyclicBarrier = new CyclicBarrier(2);
for (int i = 0; i < 2; i++) {
new Thread(() -> {
String name = Thread.currentThread().getName();
if (name.equals("Thread-0")) {
name = "3y";
} else {
name = "女朋友";
}
System.out.println(name + "到了体育西");
try {
// 两个人都要到体育西才能发朋友圈
CyclicBarrier.await();
// 他俩到达了体育西,看见了对方发了一条朋友圈:
System.out.println("跟" + name + "去夜上海吃东西~");
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}).start();
}
}
}
Результаты теста:
Поиграв сутки,иди домой, 3г договорился со своей девушкойОбщение после каждого купания
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
public class Test {
public static void main(String[] args) {
final CyclicBarrier CyclicBarrier = new CyclicBarrier(2);
for (int i = 0; i < 2; i++) {
new Thread(() -> {
String name = Thread.currentThread().getName();
if (name.equals("Thread-0")) {
name = "3y";
} else {
name = "女朋友";
}
System.out.println(name + "到了体育西");
try {
// 两个人都要到体育西才能发朋友圈
CyclicBarrier.await();
// 他俩到达了体育西,看见了对方发了一条朋友圈:
System.out.println("跟" + name + "去夜上海吃东西~");
// 回家
CyclicBarrier.await();
System.out.println(name + "洗澡");
// 洗澡完之后一起聊天
CyclicBarrier.await();
System.out.println("一起聊天");
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}).start();
}
}
}
Результаты теста:
Использованная литература:
В-третьих, СЕМАФОР
3.1 Введение в семафор
Semaphores are often used to restrict the number of threads than can access some (physical or logical) resource.
- A counting semaphore. Conceptually, a semaphore maintains a set of permits. Each {@link #acquire} blocks if necessary until a permit is available, and then takes it. Each {@link #release} adds a permit,potentially releasing a blocking acquirer.However, no actual permit objects are used; the {@code Semaphore} just keeps a count of the number available and acts accordingly.
Семафор (семафор) на самом деле управляемыйКоличество потоков, обращающихся одновременно, который поддерживает набор **"лицензий"**.
- при звонке
acquire()
Когда метод будет потреблять лицензию. Без лицензии и заблокируют - при звонке
release()
метод, добавляется лицензия. - Количество этих «лицензий» на самом деле является переменной-счетчиком~
3.2 Пример семафора
Подруга 3y открыла небольшой магазин по продаже йогурта, магазин может вместить только 5 клиентов, чтобы выбрать и купить за раз, более 5 клиентов должны стоять в очереди~~~
import java.util.concurrent.Semaphore;
public class Test {
public static void main(String[] args) {
// 假设有50个同时来到酸奶店门口
int nums = 50;
// 酸奶店只能容纳10个人同时挑选酸奶
Semaphore semaphore = new Semaphore(10);
for (int i = 0; i < nums; i++) {
int finalI = i;
new Thread(() -> {
try {
// 有"号"的才能进酸奶店挑选购买
semaphore.acquire();
System.out.println("顾客" + finalI + "在挑选商品,购买...");
// 假设挑选了xx长时间,购买了
Thread.sleep(1000);
// 归还一个许可,后边的就可以进来购买了
System.out.println("顾客" + finalI + "购买完毕了...");
semaphore.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
}
}
}
Выходной результат:
В любом случае, каждый раз5 клиентов одновременноЗайдите в магазин йогуртов, чтобы купить и выбрать.
Использованная литература:
4. Резюме
Java дает намТри класса инструментов синхронизации:
- CountDownLatch (защелка)
- Поток ожидает другого потокаПосле казни, он выполняется (другие потоки ждут потокаПосле казни, он выполняется)
- циклическийбарьер
- набор нитейждать друг друга до определенного состояния, эта группа потоков будет выполняться одновременно.
- Семафор (семафор)
- Управление группой потоков для одновременного выполнения.
В этой статье кратко рассказывается, для чего используются эти три класса инструментов синхронизации.Углубленный взгляд на исходный кодИли узнать из других источников.
Наконец, добавьте предыдущие точки знаний ментальной карты:
Использованная литература:
- «Практика параллельного программирования на Java»
- блог woo woo woo.cn на.com/dolphin0520…
- zhuanlan.zhihu.com/p/27829595
Если в статье есть какие-либо ошибки, пожалуйста, поправьте меня, и мы сможем общаться друг с другом. Учащиеся, привыкшие читать технические статьи в WeChat и желающие получить больше ресурсов по Java, могутОбратите внимание на публичный аккаунт WeChat: Java3y.
Оглавление Навигация по статьям: