当有多个线程需要start时,这时它们的运行顺序是不一定的,虽然如果你在主线程里假如是t1.start();t2.start();,可能大多数情况是t1先运行,但是也有可能是t2先运行。
两个线程
通过有一个布尔的Boolean runflag 来标记谁先运行
wait()/notifyAll()实现
实现先让t2先运行然后在t1
public class Test_has {
static private byte lock[]=new byte[0];
static private Boolean runflag=false;
public static void main(String[] args) {
Thread t1=new Thread(()->{
synchronized (lock){
while (!runflag){//runflag为false那么说明是t1先获得的锁,所以让它wait释放锁
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("t1运行");
}
},"t1");
Thread t2=new Thread(()->{
synchronized (lock){
lock.notifyAll();
runflag=true;
System.out.println("t2运行");
}
},"t2");
t1.start();
t2.start();
}
}
await()/signalAll()实现
public class Test_has {
static private ReentrantLock lock=new ReentrantLock();
static private Boolean runflag=false;
public static void main(String[] args) {
Condition condition = lock.newCondition();
Thread t1=new Thread(()->{
lock.lock();
try{
while (!runflag){//runflag为false那么说明是t1先获得的锁,所以让它wait释放锁
try {
condition.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("t1运行");
}finally {
lock.unlock();
}
},"t1");
Thread t2=new Thread(()->{
lock.lock();
try {
condition.signalAll();
runflag=true;
System.out.println("t2运行");
}finally {
lock.unlock();
}
},"t2");
t1.start();
t2.start();
}
}
多个线程
wait()/notifyAll()实现
通过int类型的runflag来标记运行线程的次序
三个线程按照t2->t3->t1的顺序运
线程 运行标记 下一个运行标记
t1 1 2
t2 2 3
t3 3 1
public class Test_has {
public static void main(String[] args) {
Wait_Notify waitNotify=new Wait_Notify(2);
new Thread(()->{
waitNotify.print("我是t1",1,2);
},"t1").start();
new Thread(()->{
waitNotify.print("我是t2",2,3);
},"t2").start();
new Thread(()->{
waitNotify.print("我是t3",3,1);
},"t3").start();
}
}
class Wait_Notify{
private int runflag;//标志当前可运行的标记
public Wait_Notify(int runflag) {//第一次从哪个线程开始
this.runflag = runflag;
}
public void print(String str, int myrunflag, int nextrunflag){
for (int i = 0; i <10; i++) {
synchronized (this){
while (runflag!=myrunflag){//当前线程运行的标记不是可运行的标记
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//当前标记等于当前线程可以运行的标记则运行
System.out.println(str);
runflag=nextrunflag;
this.notifyAll();
}
}
}
}
await()/signalAll()实现
通过ReentrantLock条件变量的特性,不同的线程可以进入不同的等待队列等待。主线程开始唤醒第一个等待队列里的线程,所有线程开始都进入到各自的等待队列进行等待直到其他线程唤醒。
public class Test_has {
public static void main(String[] args) throws InterruptedException {
AwaitSignal awaitSignal=new AwaitSignal();
Condition t1_condition = awaitSignal.newCondition();
Condition t2_condition = awaitSignal.newCondition();
Condition t3_condition = awaitSignal.newCondition();
new Thread(()->{
awaitSignal.print("我是t1",t1_condition,t3_condition);
},"t1").start();
new Thread(()->{
awaitSignal.print("我是t2",t2_condition,t1_condition);
},"t2").start();
new Thread(()->{
awaitSignal.print("我是t3",t3_condition,t2_condition);
},"t3").start();
Thread.sleep(100);
awaitSignal.lock();
t2_condition.signalAll();
awaitSignal.unlock();
}
}
class AwaitSignal extends ReentrantLock{
public void print(String str,Condition nowcon,Condition nextcon){
for (int i = 0; i <5; i++) {
this.lock();
try{
nowcon.await();
System.out.println(str);
nextcon.signalAll();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
this.unlock();
}
}
}
}