当前位置:网站首页>线程交替输出(你能想出几种方法)
线程交替输出(你能想出几种方法)
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();
}
}
边栏推荐
猜你喜欢
unable to extend table xxx by 1024 in tablespace xxxx
Daily sql--statistics the total salary of employees in the past three months (excluding the latest month)
ssh服务攻防与加固
淘宝API常用接口与获取方式
Daily sql-employee bonus filtering and answer rate ranking first
【latex异常和错误】Missing $ inserted.<inserted text>You can‘t use \spacefactor in math mode.输出文本要注意特殊字符的转义
每日sql-员工奖金过滤和回答率排序第一
Daily sql-seek the sum of successful investments in 2016
一张图了解JVM八大原子操作
Daily sql: request for friend application pass rate
随机推荐
Attitude solution - gyroscope + Euler method
每日sql--统计员工近三个月的总薪水(不包括最新一个月)
SQL滑动窗口
docker安装mysql5.7(仅供测试使用)
下一代 无线局域网--强健性
概念名词解释
亚马逊API接口大全
radix-4 FFT principle and C language code implementation
radix-4 FFT 原理和C语言代码实现
【深度学习】什么是互信息最大化?
如何选择专业、安全、高性能的远程控制软件
Taobao product details API interface
李沐d2l(十)--卷积层Ⅰ
每日sql-找到每个学校gpa最低的同学(开窗)
Daily sql-statistics of the number of professionals (including the number of professionals is 0)
JD.com product details API call example explanation
Production and optimization of Unity game leaderboards
Amazon Get AMAZON Product Details API Return Value Description
Taobao API common interface and acquisition method
Douyin API interface