1。使用Thread.join()方法在一个线程中调用另一个线程的join()方法,使该线程等待另一个线程执行完成后再继续执行。您可以通过在需要等待的线程之后调用join()方法来控制线程的执行顺序。Threadt1=newThread(newRunnable(){publicvoidrun(){//执行一些任务}});Threadt2=newThread(newRunnable(){publicvoidrun(){//等待线程t1completetry{t1.join();}catch(InterruptedExceptione){e.printStackTrace();}//继续执行一些任务}});t1.start();t2.start();在这个例子中,t2线程会等待t1线程执行完后再执行,这样可以保证t1先执行。2.使用Lock和Condition可以使用Lock和Condition来控制线程的执行顺序。Lock可以创建多个Condition对象,每个Condition对象可以控制一个线程的执行顺序。使用Condition的await()方法让线程等待,使用signal()方法唤醒等待的线程。classShareResourceLock{//线程执行条件1:线程1执行2:线程2执行3:线程3执行intnumber=1;//锁Locklock=newReentrantLock();//从锁中获取3个条件变量Conditioncondition1=lock.newCondition();条件condition2=lock.newCondition();条件condition3=lock.newCondition();//第一个线程运行后执行的方法publicvoidf1(){lock.lock();try{//如果条件值不为1,挂起等待while(number!=1){System.out.println(Thread.currentThread().getName()+"await...");条件1.等待();}//故意阻塞100毫秒,看看其他线程是否会不再排队inti=newRandom().nextInt(2000);整数sleepTime=1000+i;Thread.sleep(sleepTime);系统。out.println(Thread.currentThread().getName()+"执行"+sleepTime);System.out.println("------1--------");//线程1执行后,设置变量为2number=2;//唤醒第二个条件变量条件2.信号();}catch(Exceptione){e.printStackTrace();}finally{//不管是否抛出异常都解锁,防止线程死锁lock.unlock();}}publicvoidf2(){lock.lock();尝试{while(number!=2){System.out.println(Thread.currentThread().getName()+"await...");条件2.等待();}inti=newRandom().nextInt(2000);整数sleepTime=1000+i;Thread.sleep(sleepTime);System.out.println(Thread.currentThread().getName()+"执行"+sleepTime);.out.println("------2--------");数=3;条件3.信号();}catch(Exceptione){e.printStackTrace();}最后{lock.unlock();}}publicvoidf3(){lock.lock();试试{while(number!=3){System.out.println(Thread.currentThread().getName()+"await...");condition3.await();}inti=newRandom().nextInt(2000);整数sleepTime=1000+i;Thread.sleep(sleepTime);System.out.println(Thread.currentThread().getName()+"执行"+sleepTime);System.out.println("------3--------");数=1;条件1.信号();}catch(Exceptione){e.printStackTrace();}最后{lock.unlock();}}}publicclassThreadOrderExecute{publicstaticvoidmain(String[]args)throwsInterruptedException{ShareResourceLockshareDataLock=newShareResourceLock();Threadt1=newThread(()->shareDataLock.f1(),"aa");Threadt2=newThread(()->shareDataLock.f2(),"bb");线程t3=newThread(()->shareDataLock.f3(),"cc");t1.开始();t2.开始();t3.开始();t1.join();t2.join();t3.join();}}在这个例子中,t2线程会在t1线程执行完后被唤醒,t3线程会在t2线程执行完后被唤醒,这样可以保证线程的执行顺序。注意await()和signal()方法必须在lock.lock()和lock.unlock()中,否则会抛出IllegalMonitorStateException。这些方法可以达到线程按照特定顺序执行的效果,选择哪种方法要看具体情况和需求。3.举个反面例子,注意执行顺序//从锁中获取3个条件变量Conditioncondition2=lock.newCondition();条件condition3=lock.newCondition();Threadt1=newThread(newRunnable(){@Overridepublicvoidrun(){lock.lock();try{//如果条件值不为1则挂断等待System.out.println("------1--------");//唤醒第二个条件变量condition2.signal();}catch(Exceptione){e.printStackTrace();}finally{//不管怎样都解锁是否抛出异常防止线程死锁lock.unlock();}}},"aa");Threadt2=newThread(newRunnable(){@Overridepublicvoidrun(){锁.锁();尝试{System.out.println("------t2await------");条件2.等待();//如果条件值不为1则挂起WaitforSystem.out.println("------2--------");//唤醒第二个条件变量condition3.signal();}赶上(异常e){e。打印堆栈跟踪();}最后{lock.unlock();}}},"bb");Threadt3=newThread(newRunnable(){@Overridepublicvoidrun(){lock.lock();try{System.out.println("------t3await------");condition3.await();//如果条件值不为1,挂断等待System.out.println("------3--------");}catch(异常e){e.printStack痕迹();}finally{//不管是否抛出异常都解锁,防止线程死锁lock.unlock();}}},"cc");//正确的打开方式//t3.start();//Thread.sleep(1000);//t2.start();//Thread.sleep(1000);//t1.start();//登录方式有问题,可能会出现t1线程执行condition2.signal();//但是t2线程还没有执行condition2.await();所以会出现t2线程一直在等待t1.join()的情况;t2.join();t3.join();}}上面的例子中,线程t1、t2、t3的执行顺序影响比较大。如果按照t1、t2、t3的顺序执行,线程t1可能会执行condition2.signal();但是线程t2还没有执行condition2。。等待();最后的结果是t1执行了condition2.signal(),但是t2线程没有收到,导致t2线程一直等待
