目标
多个线程如何控制先后顺序
学习总结
- 通过join控制,原理,让父线程等待子线程结束之后才能继续运行,看下线程流程图:
再看下源码:
public final synchronized void join(long millis)
throws InterruptedException {
long base = System.currentTimeMillis();
long now = 0;
if (millis < 0) {
throw new IllegalArgumentException("timeout value is negative");
}
if (millis == 0) {
while (isAlive()) {
wait(0);
}
} else {
//线程会一直检测所属实例线程状态是否为active状态,直到实例子线程结束后,才执行原有父线程.
while (isAlive()) {
long delay = millis - now;
if (delay <= 0) {
break;
}
wait(delay);
now = System.currentTimeMillis() - base;
}
}
}
看下测试demo
Thread t1=new Thread(()->{
System.out.println("线程1");
});
Thread t2=new Thread(()->{
t1.start();
try {
t1.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("线程2");
});
Thread t3=new Thread(()->{
t2.start();
try {
t2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("线程3");
});
t3.start();
- 通过线程池技术实现
public static void main(String[] args) {
Thread t1=new Thread(()->{
System.out.println("线程1");
});
Thread t2=new Thread(()->{
System.out.println("线程2");
});
Thread t3=new Thread(()->{
System.out.println("线程3");
});
Thread t4=new Thread(()->{
System.out.println("线程4");
});
ExecutorService executorService= Executors.newSingleThreadExecutor();
executorService.execute(t1);
executorService.execute(t2);
executorService.execute(t3);
executorService.execute(t4);
}
- 通过Lock锁实现,
注意,Condition 类必须在Lock.lock和Lock.unLock中使用!
package suanfa.join;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class TestLock {
public static void main(String[] args) {
Lock lock = new ReentrantLock();
Condition condition1 = lock.newCondition();
Condition condition2 = lock.newCondition();
Condition condition3 = lock.newCondition();
Condition condition4 = lock.newCondition();
Test1 test1 = new Test1(lock, condition1,condition2,"线程1").first();
Test1 test2 = new Test1(lock, condition2,condition3,"线程2");
Test1 test3 = new Test1(lock, condition3,condition4,"线程3");
Test1 test4 = new Test1(lock, condition4,null,"线程4");
new Thread(test3).start();
new Thread(test2).start();
new Thread(test4).start();
new Thread(test1).start();
}
public static void testLock(Lock lock, Condition condition, Condition next, Runnable runnable,boolean isFirst,String threadName) {
try {
lock.lock();
if(!isFirst) {
condition.await();
}
System.out.println(threadName
+ " 开始执行");
if (next != null)
next.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
class Test1 implements Runnable {
private Lock lock;
private Condition condition;
private Condition next;
private boolean isFirst;
private String threadName;
public Test1(Lock lock, Condition condition, Condition next, String threadName) {
this.lock = lock;
this.condition = condition;
this.next = next;
this.threadName = threadName;
}
public Test1 first() {
this.isFirst = true;
return this;
}
@Override
public void run() {
TestLock.testLock(lock, condition, next, this,isFirst,threadName);
}
}
结果
线程1 开始执行
线程2 开始执行
线程3 开始执行
线程4 开始执行
网友评论