java并发编程学习--控制线程顺序

2019-03-10  本文已影响0人  爱编程的凯哥

目标

多个线程如何控制先后顺序

学习总结

  1. 通过join控制,原理,让父线程等待子线程结束之后才能继续运行,看下线程流程图:
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();
  1. 通过线程池技术实现
    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);

    }
  1. 通过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  开始执行
上一篇 下一篇

猜你喜欢

热点阅读