您的位置 首页 java

Java,多线程,保证线程的执行顺序,总结了4种方法实现及代码

前言

多个 线程 执行如何保证顺序,这里总结了4种方法:

1、线程的协作(联合)机制实现。

2、线程的等待和唤醒机制实现,缺点:wait和notify不能脱离 synchronized 代码块或者synchronized方法独自运行。

3、使用 Lock 及Condition对象实现。

4、使用 lock Support实现, 阻塞:LockSupport.park()和唤醒:LockSupport.unpark(thread)。

实现

方式1:线程的协作(联合)机制

 public class  Thread Demo01 {

    public  static   void  main(String[] args) {
        System.out.println("▶▶▶▶▶ 主程序开始");
        Thread thread =  null ;
        for (int i = 0; i < 9; i++) {
            MyRunnable myRunnable = new MyRunnable("我是线程:" + (i + 1), thread);
            Thread exeThread = new Thread(myRunnable);
            exeThread.start();
            thread = exeThread;
        }
        System.out.println("◀◀◀◀◀ 主程序结束");

    }

    static class MyRunnable implements Runnable {

         private  String name;

        private Thread thread;

        MyRunnable(String name, Thread thread) {
            this.name = name;
            this.thread = thread;
        }

        @Override
        public void run() {
            if (thread != null) {
                try {
                    // 把指定的线程加入到当前线程
                    thread.join();
                } catch (Interrupted Exception  e) {
                    e.printStackTrace();
                }
            }
            try {
                Thread.sleep(30);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("[" + this.name + "]正在执行中.");
        }
    }

}  

方式2:线程的等待和唤醒机制

 import  java .util.concurrent.TimeUnit;

public class ThreadDemo0203 {

    public static void main(String[] args) {
        System.out.println("▶▶▶▶▶ 主程序开始");
        Object curtLock = null;
        Object nextLock = null;
        for (int i = 0; i < 9; i++) {
            if (i == 0) {
                // 第一个
                curtLock = null;
                nextLock = new Object();
            } else if (i == 8) {
                // 最后一个
                curtLock = nextLock;
                nextLock = null;
            } else {
                // 中间态
                curtLock = nextLock;
                nextLock = new Object();
            }
            MyRunnable myRunnable = new MyRunnable("我是线程:" + (i + 1), curtLock, nextLock);
            Thread exeThread = new Thread(myRunnable);
            exeThread.start();

        }
        System.out.println("◀◀◀◀◀ 主程序结束");
    }

    static class MyRunnable implements Runnable {

        private String name;

        private Object curtLock;

        private Object nextLock;

        MyRunnable(String name, Object curtLock, Object nextLock) {
            this.name = name;
            this.curtLock = curtLock;
            this.nextLock = nextLock;
        }

        @Override
        public void run() {
            if (this.curtLock == null) {
                // 先等待一下再执行
                try {
                    TimeUnit.SECONDS.sleep(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized (this.nextLock) {
                    // 业务代码
                    execute(this.name);
                    // 发出通知
                    if (this.nextLock != null) {
                        this.nextLock.notify();
                    }
                }
            } else {
                synchronized (this.curtLock) {
                    // 进入等待
                    try {
                        this.curtLock.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    // 业务代码
                    execute(this.name);
                    // 发出通知
                    if (this.nextLock != null) {
                        synchronized (this.nextLock) {
                            this.nextLock.notify();
                        }
                    }
                }
            }
        }

        private void execute(String name) {
            try {
                Thread.sleep(30);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("[" + name + "]正在执行中.");
        }
    }

}  

循序渐进1

 import java.util.concurrent.TimeUnit;

public class ThreadDemo02 {

    public static void main(String[] args) {
        System.out.println("▶▶▶▶▶ 主程序开始");
        // wait + notify不能脱离synchronized代码块或者方法;
        // wait + notify顺序不能颠倒,只能先等待后唤醒
        Object lock = new Object();
        new Thread(new MyRunnable1("线程1", lock)).start();
        new Thread(new MyRunnable2("线程2", lock)).start();
        System.out.println("◀◀◀◀◀ 主程序结束");
    }

    static class MyRunnable1 implements Runnable {

        private String name;

        private Object lock;

        MyRunnable1(String name, Object lock) {
            this.name = name;
            this.lock = lock;
        }

        @Override
        public void run() {
            // wait + notify顺序不能颠倒,只能先等待后唤醒
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            synchronized (lock) {
                execute(this.name);
                lock.notify();
            }
        }

    }

    static class MyRunnable2 implements Runnable {

        private String name;

        private Object lock;

        MyRunnable2(String name, Object lock) {
            this.name = name;
            this.lock = lock;
        }

        @Override
        public void run() {
            synchronized (lock) {
                try {
                    lock.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                execute(this.name);
            }
        }
    }

    private static void execute(String name) {
        try {
            Thread.sleep(30);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("[" + name + "]正在执行中.");
    }

}  

循序渐进2

 import java.util.concurrent.TimeUnit;

public class ThreadDemo0202 {

    public static void main(String[] args) {
        System.out.println("▶▶▶▶▶ 主程序开始");
        Object lock = new Object();
        Object lock2 = new Object();
        new Thread(new MyRunnable1("线程1", lock)).start();
        new Thread(new MyRunnable2("线程2", lock, lock2)).start();
        new Thread(new MyRunnable3("线程3", lock2)).start();
        System.out.println("◀◀◀◀◀ 主程序结束");
    }

    static class MyRunnable1 implements Runnable {

        private String name;

        private Object lock;

        MyRunnable1(String name, Object lock) {
            this.name = name;
            this.lock = lock;
        }

        @Override
        public void run() {
            // wait + notify顺序不能颠倒,只能先等待后唤醒
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            synchronized (lock) {
                execute(this.name);
                lock.notify();
            }
        }

    }

    static class MyRunnable2 implements Runnable {

        private String name;

        private Object lock;

        private Object lock2;

        MyRunnable2(String name, Object lock, Object lock2) {
            this.name = name;
            this.lock = lock;
            this.lock2 = lock2;
        }

        @Override
        public void run() {
            synchronized (this.lock) {
                try {
                    lock.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                execute(this.name);
                //
                synchronized (this.lock2) {
                    lock2.notify();
                }
            }
        }
    }

    static class MyRunnable3 implements Runnable {

        private String name;

        private Object lock2;

        MyRunnable3(String name, Object lock2) {
            this.name = name;
            this.lock2 = lock2;
        }

        @Override
        public void run() {
            synchronized (this.lock2) {
                try {
                    lock2.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                execute(this.name);
            }
        }
    }

    private static void execute(String name) {
        try {
            Thread.sleep(30);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("[" + name + "]正在执行中.");
    }

}  

方式3:互斥锁Lock及Condition

 import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class ThreadDemo03 {

    public static void main(String[] args) {
        // lock和await和signal必须一起使用才行,await和 signal 不能脱离lock单独使用;
        // 必须要先等待,后唤醒;顺序不能颠倒。
        System.out.println("▶▶▶▶▶ 主程序开始");
        Lock lock = new ReentrantLock();
        Condition curtCondition = null;
        Condition nextCondition = null;
        for (int i = 0; i < 9; i++) {
            if (i == 0) {
                // 第一个
                curtCondition = null;
                nextCondition = lock.newCondition();
            } else if (i == 8) {
                // 最后一个
                curtCondition = nextCondition;
                nextCondition = null;
            } else {
                // 中间态
                curtCondition = nextCondition;
                nextCondition = lock.newCondition();
            }
            MyRunnable myRunnable = new MyRunnable("我是线程:" + (i + 1), lock, curtCondition, nextCondition);
            Thread exeThread = new Thread(myRunnable);
            exeThread.start();
        }
        System.out.println("◀◀◀◀◀ 主程序结束");
    }

    static class MyRunnable implements Runnable {

        private String name;
        private Lock lock;
        private Condition curtCondition;
        private Condition nextCondition;

        public MyRunnable(String name, Lock lock, Condition curtCondition, Condition nextCondition) {
            this.name = name;
            this.lock = lock;
            this.curtCondition = curtCondition;
            this.nextCondition = nextCondition;
        }

        @Override
        public void run() {
            if (curtCondition == null) {
                // 先等待一下再执行
                try {
                    TimeUnit.SECONDS.sleep(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                try {
                    lock.lock();
                    // 执行业务
                    this.execute(this.name);
                    // 发出通知
                    if (this.nextCondition != null) {
                        // lock和await和signal必须一起使用才行,await和signal不能脱离lock单独使用
                        this.nextCondition.signal();
                    }
                } finally {
                    lock.unlock();
                }
            } else {
                try {
                    lock.lock();
                    // 进入等待
                    try {
                        // lock和await和signal必须一起使用才行,await和signal不能脱离lock单独使用
                        this.curtCondition.await();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                } finally {
                    lock.unlock();
                }
                // 执行业务
                this.execute(this.name);
                try {
                    lock.lock();
                    // 发出通知
                    if (this.nextCondition != null) {
                        this.nextCondition.signal();
                    }
                } finally {
                    lock.unlock();
                }
            }
        }

        private void execute(String name) {
            try {
                Thread.sleep(30);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("[" + name + "]正在执行中.");
        }
    }

}  

方式4:LockSupport类

 import java.util.concurrent.locks.LockSupport;

public class ThreadDemo0402 {

    public static void main(String[] args) {
        System.out.println("▶▶▶▶▶ 主程序开始");
        Thread nextThread = null;
        for (int i = 8; i > 0; i--) {
            int status = (i == 1) ? 1 : 0;
            Thread exeThread = new Thread(new MyRunnable("我是线程:" + (i), status, nextThread));
            exeThread.start();
            nextThread = exeThread;
        }
        System.out.println("◀◀◀◀◀ 主程序结束");
    }

    static class MyRunnable implements Runnable {

        private String name;

        private int status;

        private Thread thread;

        MyRunnable(String name, int status, Thread thread) {
            this.name = name;
            this.status = status;
            this.thread = thread;
        }

        @Override
        public void run() {
            if (status == 1) {
                // 业务代码
                this.execute(this.name);
                // 唤醒线程
                if (thread != null) {
                    LockSupport.unpark(thread);
                }
            } else if (status == 0) {
                // 阻塞
                LockSupport.park();
                // 业务代码
                this.execute(this.name);
                // 唤醒线程
                if (thread != null) {
                    LockSupport.unpark(thread);
                }
            }
        }

        private void execute(String name) {
            try {
                Thread.sleep(30);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("[" + name + "]正在执行中.");
        }
    }

}  

循序渐进:

 import java.util.concurrent.locks.LockSupport;

public class ThreadDemo04 {

    public static void main(String[] args) {
        // Posix线程库
        // 阻塞线程  LockSupport.park();
        // 唤醒线程: LockSupport.unpark();
        Thread thread2 = new Thread(new MyRunnable("线程2", null));
        Thread thread1 = new Thread(new MyRunnable("线程1", thread2));
        thread1.start();
        thread2.start();
    }

    static class MyRunnable implements Runnable {

        private String name;

        private Thread thread;

        MyRunnable(String name, Thread thread) {
            this.name = name;
            this.thread = thread;
        }

        @Override
        public void run() {
            if (thread == null) {
                // 阻塞
                LockSupport.park();
                // 业务代码
                this.execute(this.name);
            } else {
                // 业务代码
                this.execute(this.name);
                // 唤醒
                LockSupport.unpark(thread);
            }
        }

        private void execute(String name) {
            try {
                Thread.sleep(30);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("[" + name + "]正在执行中.");
        }
    }

}  

文章来源:智云一二三科技

文章标题:Java,多线程,保证线程的执行顺序,总结了4种方法实现及代码

文章地址:https://www.zhihuclub.com/200139.shtml

关于作者: 智云科技

热门文章

网站地图