当前位置:网站首页>线程交替输出(你能想出几种方法)
线程交替输出(你能想出几种方法)
2022-08-11 06:33:00 【明天一定.】
前提
关于线程的解决思路,最好不要从时间角度,优先级角度考虑。一般不要使用sleep和join。
LockSupport
LockSupport.unpark(); LockSupport.park();
public class A {
static Thread t1 = null;
static Thread t2 = null;
public static void main(String[] args) {
String[] a = {"1","2","3","4","5"};
String[] b = {"a","b","c","d","e"};
t1 = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < a.length; i++) {
System.out.println(a[i]);
LockSupport.unpark(t2);
LockSupport.park();
}
}
});
t2 = new Thread(()->{
for (int i = 0; i < b.length; i++) {
LockSupport.park();
System.out.println(b[i]);
LockSupport.unpark(t1);
}
});
t1.start();
t2.start();
}
}
ReentrantLock
针对线程通信这块,比起使用wait和notify更灵活,因为可以指定多个condition
lock.newCondition() condition.signal(); condition.await();
public class C {
static CountDownLatch latch = new CountDownLatch(1); //可以指定谁先执行时使用,具体看B类
static ReentrantLock lock = new ReentrantLock();
static Condition condition1 = lock.newCondition();
static Condition condition2 = lock.newCondition();
public static void main(String[] args) {
String[] a = {"1","2","3","4","5"};
String[] b = {"a","b","c","d","e"};
C c = new C();
new Thread(()->{
c.t1(a);
}).start();
new Thread(()->{
c.t2(b);
}).start();
}
void t1(String[] a) {
lock.lock();
for (int i = 0; i < a.length; i++) {
try {
System.out.println(a[i]);
condition1.signal();
condition2.await();
} catch (Exception e) {
e.printStackTrace();
}
condition1.signal();
}
lock.unlock();
}
void t2(String[] b){
lock.lock();
for (int i = 0; i < b.length; i++) {
try {
System.out.println(b[i]);
condition2.signal();
condition1.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
condition2.signal();
}
lock.unlock();
}
}
在这里可以看知道两个线程确实交替执行了(暂时没有控制线程先后顺序),但是,如果我想控制让哪个线程先执行,需要怎么做?想一想,在使用wait和notify的案例中给出答案。
wait、notify
synchronized notify(); wait();
可以看一下如何控制哪个线程先输出
public class B {
static CountDownLatch latch = new CountDownLatch(1);
public static void main(String[] args) {
String[] a = {"1","2","3","4","5"};
String[] b = {"a","b","c","d","e"};
B b1 = new B();
new Thread(()->{
b1.t1(a);
}).start();
new Thread(()->{
b1.t2(b);
}).start();
}
void t1(String[] a) {
try {
latch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (this){
for (int i = 0; i < a.length; i++) {
try {
System.out.println(a[i]);
notify();
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
notify();
}
}
void t2(String[] b){
synchronized (this){
for (int i = 0; i < b.length; i++) {
try {
System.out.println(b[i]);
latch.countDown();
notify();
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
notify();
}
}
}
LinkedTransferQueue
LinkedTransferQueue是一个由链表结构组成的无界阻塞TransferQueue队列。
LinkedTransferQueue
是SynchronousQueue
和LinkedBlockingQueue
的合体,性能比LinkedBlockingQueue
更高(没有锁操作),比SynchronousQueue
能存储更多的元素。相对于其他阻塞队列,LinkedTransferQueue多了tryTransfer和transfer方法。
transfer:调用此方法后要等到有消费者获取此元素之后才返回,不然就一直阻塞。
take和poll: 如果为空就一直阻塞.
public class D {
public static void main(String[] args) {
String[] a = {"1","2","3","4","5"};
String[] b = {"a","b","c","d","e"};
LinkedTransferQueue<String> queue = new LinkedTransferQueue<>();
new Thread(()->{
try {
for (int i = 0; i < a.length; i++) {
System.out.println(queue.take());
queue.transfer(a[i]);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
new Thread(()->{
for (int i = 0; i < b.length; i++) {
try {
queue.transfer(b[i]);
System.out.println(queue.take());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
}
边栏推荐
- 软件测试基本流程有哪些?北京专业第三方软件检测机构安利
- Daily sql: request for friend application pass rate
- Pytorch模型转ONNX模型
- 李沐d2l(十)--卷积层Ⅰ
- 淘宝API接口参考
- 2022-08-09 第四小组 修身课 学习笔记(every day)
- js根据当天获取前几天的日期
- 1688 product interface
- When MySQL uses GROUP BY to group the query, the SELECT query field contains non-grouping fields
- 第一个C函数:如何实现板级初始化?
猜你喜欢
linux 安装mysql服务报错
Implementation of FIR filter based on FPGA (5) - FPGA code implementation of parallel structure FIR filter
buu—Re(5)
每日sql-员工奖金过滤和回答率排序第一
公牛10-11德里克·罗斯最强赛季记录
拼多多API接口大全
A used in the study of EEG ultra scanning analysis process
Strongly recommend an easy-to-use API interface
Get Pinduoduo product information operation details
恒源云-Pycharm远程训练避坑指南
随机推荐
Daily sql-employee bonus filtering and answer rate ranking first
Unity3D 学习路线?
LeetCode刷题系列 -- 46. 全排列
Spatial Pyramid Pooling -Spatial Pyramid Pooling (including source code)
Amazon API interface Daquan
Edge 提供了标签分组功能
每日sql:求好友申请通过率
每日sql-统计各个专业人数(包括专业人数为0的)
淘宝API常用接口与获取方式
MySQL 版本升级心得
京东商品详情API调用实例讲解
一张图了解JVM八大原子操作
拼多多API接口(附上我的可用API)
buu—Re(5)
技术分享 | 实战演练接口自动化如何处理 Form 请求?
1688商品详情接口
从苹果、SpaceX等高科技企业的产品发布会看企业产品战略和敏捷开发的关系
SQL sliding window
Redis源码-String:Redis String命令、Redis String存储原理、Redis字符串三种编码类型、Redis String SDS源码解析、Redis String应用场景
Edge provides label grouping functionality