java 中线程交互的方式多种多样,你可能需要都看一下。
Thread.join()
最简单的就是通过线程的join方法进行交互。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17public static void main(String[] args) throws Exception {
Thread thread1 = new Thread(() -> {
try {
Thread.sleep(5000);
System.out.println("thread1 finish");
} catch (InterruptedException e) {
e.printStackTrace();
}
});
Thread thread12 = new Thread(() -> System.out.println("thread2 finish"));
thread11.start();
thread2.start();
thread1.join();
thread2.join();
System.out.println("all thread finish");
}
执行结果
1
2
3thread1 finish
thread2 finish
all thread finish
join方法用于让当前执行线程等待join线程执行结束。其实现原理是不停检查,join线程是否存活,如果join线程存活则让当前线程永远等待。
CountDownLatch
1 | public static void main(String[] args) throws Exception { |
执行结果
1
2
31
2
3
CyclicBarrier
同步屏障,CyclicBarrier的字面意思是可循环使用(Cyclic)的屏障(Barrier)。CyclicBarrier的字面意思是可循环使用(Cyclic)的屏障(Barrier)。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 public static void main(String[] args) throws Exception {
CyclicBarrier c = new CyclicBarrier(2);
new Thread(() -> {
try {
c.await();
} catch (Exception e) {
}
System.out.println(1);
}).start();
Thread.sleep(2000);
System.out.println(2);
try {
c.await();
} catch (Exception e) {
}
}
执行结果
1
22
1
CyclicBarrier还提供一个更高级的构造函数CyclicBarrier(int parties,Runnable barrier-Action) ,用于在线程到达屏障时,优先执行barrierAction,方便处理更复杂的业务场景。
CyclicBarrier和CountDownLatch的区别,CountDownLatch的计数器只能使用一次,而CyclicBarrier的计数器可以使用reset()方法重置,同时CyclicBarrier还提供其他有用的方法,比如getNumberWaiting方法可以获得CyclicBarrier阻塞的线程数量。isBroken()方法用来了解阻塞的线程是否被中断。
Semaphore
信号量:是用来控制同时访问特定资源的线程数量,它通过协调各个线程,以保证合理的使用公共资源。Semaphore可以控制系统的流量,拿到信号量的线程可以进入,否则就等待。通过acquire()和release()获取和释放访问许可。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23public static void main(String[] args) throws Exception {
int threadCount = 30;
ExecutorService threadPool = Executors.newFixedThreadPool(threadCount);
Semaphore s = new Semaphore(5);
for (int i = 0; i < threadCount; i++) {
threadPool.execute(new Runnable() {
public void run() {
try {
s.acquire(); //获取许可证
System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()) + "\t\t\tsave data");
//每隔5s执行5个线程,直到全部执行完
Thread.sleep(5000);
s.release(); //释放许可证
} catch (InterruptedException e) {
}
}
});
}
//shutdown后不允许提交线程
threadPool.shutdown();
}
Condition
1 | public class TestCondition { |
执行结果
1
2
3
4
5当前线程:t1进入等待状态..
当前线程:t1释放锁..
当前线程:t2进入..
当前线程:t2发出唤醒..
当前线程:t1继续执行...
Exchanger
Exchanger 交换者,是用于线程间进行数据交换的。它提供一个同步点,在这个同步点两个线程可以交换数据。如果第一个线程先执行exchange()方法,它会一直等待第二个线程也执行exchange方法,当两个线程都到达同步点时,这两个线程就可以交换数据,将本线程的数据传递给对方。
1 | public static void main(String[] args) { |