关于java:java如何控制线程按照顺序执行

32次阅读

共计 2640 个字符,预计需要花费 7 分钟才能阅读完成。

1、应用 Thread.join() 办法

能够在一个线程中调用另一个线程的 join() 办法,使得该线程期待另一个线程执行实现后再继续执行。能够通过在须要期待的线程前面调用 join() 办法的形式来控制线程的执行程序。

Thread t1 = new Thread(new Runnable() {public void run() {// 执行一些工作}
});

Thread t2 = new Thread(new Runnable() {public void run() {
        // 期待 t1 线程执行实现
        try {t1.join();
        } catch (InterruptedException e) {e.printStackTrace();
        }

        // 继续执行一些工作
    }
});

t1.start();
t2.start();

在这个例子中,t2 线程在执行之前会期待 t1 线程执行实现,这样就能够保障 t1 先执行。

2、应用 Lock 和 Condition

能够应用 Lock 和 Condition 来控制线程的执行程序。Lock 能够创立多个 Condition 对象,每个 Condition 对象能够管制一个线程的执行程序。应用 Condition 的 await() 办法能够使线程期待,应用 signal() 办法能够唤醒期待的线程。


class ShareResourceLock{
    // 线程执行的条件 1:线程 1 执行 2:线程 2 执行 3:线程 3 执行
    int number =1;
    // 锁
    Lock lock = new ReentrantLock();
    // 从锁中取得 3 个条件变量
    Condition condition1 = lock.newCondition();
    Condition condition2 = lock.newCondition();
    Condition condition3 = lock.newCondition();

    // 第一个线程 run 之后执行的办法
    public void f1(){lock.lock();
        try {
            // 如果条件值不为 1 就挂起期待
            while(number!=1){System.out.println(Thread.currentThread().getName() + "await...");
                condition1.await();}
            // 成心阻塞 100 毫秒,看看其余的线程会不会不再排队
            int i= new Random().nextInt(2000);
            Integer sleepTime = 1000 + i;
            Thread.sleep(sleepTime);
            System.out.println(Thread.currentThread().getName() + "execute" + sleepTime);
            System.out.println("------1--------");
            // 线程 1 执行结束 把变量设置为 2
            number = 2;
            // 唤醒第 2 个条件变量
            condition2.signal();} catch (Exception e) {e.printStackTrace();
        } finally {
            // 不论抛没抛出异样都要解锁,避免线程死锁
            lock.unlock();}
    }

    public void f2(){lock.lock();
        try {while(number!=2){System.out.println(Thread.currentThread().getName() + "await...");
                condition2.await();}
            int i= new Random().nextInt(2000);
            Integer sleepTime = 1000 + i;
            Thread.sleep(sleepTime);
            System.out.println(Thread.currentThread().getName() + "execute" + sleepTime);
            System.out.println("------2--------");
            number = 3;
            condition3.signal();} catch (Exception e) {e.printStackTrace();
        } finally {lock.unlock();
        }
    }

    public void f3(){lock.lock();
        try {while(number!=3){System.out.println(Thread.currentThread().getName() + "await...");
                condition3.await();}
            int i= new Random().nextInt(2000);
            Integer sleepTime = 1000 + i;
            Thread.sleep(sleepTime);
            System.out.println(Thread.currentThread().getName() + "execute" + sleepTime);
            System.out.println("------3--------");
            number = 1;
            condition1.signal();} catch (Exception e) {e.printStackTrace();
        } finally {lock.unlock();
        }
    }
}


public class ThreadOrderExecute {public static void main(String[] args) throws InterruptedException {ShareResourceLock shareDataLock = new ShareResourceLock();
        Thread t1 = new Thread(()->shareDataLock.f1(),"aa");
        Thread t2 = new Thread(()->shareDataLock.f2(),"bb");
        Thread t3 = new Thread(()->shareDataLock.f3(),"cc");

        t1.start();
        t2.start();
        t3.start();

        t1.join();
        t2.join();
        t3.join();}
}

在这个例子中,t1 线程执行实现后会唤醒 t2 线程,t2 线程执行实现后会唤醒 t3 线程,这样就能够保障线程的执行程序。留神,await() 和 signal() 办法必须在 lock.lock() 和 lock.unlock() 之间调用,否则会抛出 IllegalMonitorStateException 异样。

这些办法都能够实现线程依照特定程序执行的成果,具体抉择哪种办法取决于具体的状况和需要。

正文完
 0