최근 인터뷰에서 Java 스레드의 세 가지 동기화 도구 클래스에 대한 질문을 접했습니다. 저는 멀티스레딩을 배울 때 동기화 도구 클래스를 자세히 공부하지 않았습니다. 이제는 그 일조차 잊어버렸습니다. 그래서 다시 검토해보니 꽤 심오한 내용이라 정리해서 참고용으로 글을 쓰게 되었습니다. Apache php mysql
Java는 세 가지 동기화 도구 클래스를 제공합니다.
CountDownLatch(잠금):
~ 세 가지 동기화 도구 클래스가 완료된 후 실행됩니다.)
CyclicBarrier(울타리):
스레드 그룹은 서로 특정 상태에 도달할 때까지 기다리며, 이 스레드 그룹은 동시에 실행됩니다. ㅋㅋㅋ >
솔직히 말하면 이러한 도구 클래스는 실제로
스레드 간의 통신 문제를 더 잘 제어하기 위한 것입니다~
실제로 일반적으로 사용되는 두 가지 API가 있습니다:간단히 말하면 CountDownLatch는
- 다른 스레드
기다릴 수 있도록 하는 동기화된 도우미 클래스입니다.가 완료
될 때까지 하나 이상의 스레드가
await()
및 countDown()
사용 지침:
count는 CountDownLatch를 초기화한 다음 필요한 스레드를 초기화합니다. 대기 호출 대기 방법. wait 메서드는 count=0이 될 때까지 차단됩니다. 다른 스레드는 작업을 완료한 후countDown()
을 호출하여 카운터를 1씩 감소시킵니다. count가 0으로 줄어들면 모든 대기 스레드가 해제됩니다await()
和countDown()
使用说明:
count初始化CountDownLatch,然后需要等待的线程调用await方法。await方法会一直受阻塞直到count=0。而其它线程完成自己的操作后,调用countDown()
를 통해 대기를 제어합니다. count 값이 0(다른 스레드의 작업)입니다. 완료) ), 계속해서 실행할 수 있습니다.
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는 현재 창고 모듈 기능을 담당하고 있지만 그의 능력이 너무 형편없고 쓰기 속도가 매우 느립니다.
다른 직원은 3y가 쓰기를 완료할 때까지 기다려야 합니다. 계속 쓰세요.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. CyclicBarrier
공통 장벽 지점스레드 집합이 서로 공통 장벽 지점에 도달할 때까지 기다릴 수 있도록 하는 동기화 보조 장치입니다. 때때로 서로를 기다려야 하는 고정된 크기의 스레드 파티와 관련된 프로그램에 유용합니다. 대기 스레드가 해제된 후에 다시 사용할 수 있기 때문에 장벽을
간단히 말하면: CyclicBarrier는 다음을 허용합니다. 그룹 스레드는- 주기적
이라고 합니다.
에 도달할 때까지 서로를 기다립니다. 모든 대기 스레드가 해제되면 CyclicBarrier를 재사용할 수 있기 때문에 순환이라고 합니다 (재사용할 수 없는 CountDownLatch와 대조적) 사용 지침:
, CyclicBarrier는 스레드 가 특정 상태 에 도달하면 일시 중지하고 모든 스레드가 도착 한 후에 실행이 계속된다는 점에 중점을 둡니다.
만나기로 합의했고, 만났을 때 Moments 에 메시지를 보내기로 합의했습니다. 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();
}
}
}
테스트 결과:
하루 동안 놀고
각각 집으로 돌아왔으며, 3y와 여자친구는 샤워한 후 채팅하기로 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();
}
}
}
테스트 결과:
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.
Semaphore(信号量)实际上就是可以控制同时访问的线程个数,它维护了一组"许可证"。
当调用acquire()
方法时,会消费一个许可证。如果没有许可证了,会阻塞起来
当调用release()
方法时,会添加一个许可证。
这些"许可证"的个数其实就是一个count变量罢了~
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个客户同时进酸奶小店购买挑选。
总结:本文简单的介绍了一下Java多线程的三个同步工具类的用处以及如何用,要深入还得看源码或者查阅其他的资料。如果文章有错的地方欢迎指正,大家互相交流。
相关文章:
相关视频:
위 내용은 Java 스레드의 세 가지 동기화 도구에 대한 지식 포인트 요약, 컬렉션 노트의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!