博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java:现有线程T1/T2/T3,如何确保T1执行完成之后执行T2,T3在T2执行完成之后执行。...
阅读量:5742 次
发布时间:2019-06-18

本文共 8624 字,大约阅读时间需要 28 分钟。

要实现多个线程执行完成先后,就要知道如何实现线程之间的等待,java线程等待实现是join。java的jdk中join方法实现如下:

1 public final synchronized void join(long millis) 2     throws InterruptedException { 3         long base = System.currentTimeMillis(); 4         long now = 0; 5  6         if (millis < 0) { 7             throw new IllegalArgumentException("timeout value is negative"); 8         } 9 10         if (millis == 0) {11             while (isAlive()) {12                 wait(0);13             }14         } else {15             while (isAlive()) {16                 long delay = millis - now;17                 if (delay <= 0) {18                     break;19                 }20                 wait(delay);21                 now = System.currentTimeMillis() - base;22             }23         }24     }

实现需求的方案一:

1 public class TestMain { 2     public static void main(String[] args) throws InterruptedException { 3         Thread T1 = new MyThread("T1"); 4         Thread T2 = new MyThread("T2"); 5         Thread T3 = new MyThread("T3"); 6  7         System.out.println("T1 start."); 8         T1.start(); 9         T1.join();10         System.out.println("T1 complete.");11 12         System.out.println("T2 start.");13         T2.start();14         T2.join();15         System.out.println("T2 complete.");16 17         System.out.println("T3 start.");18         T3.start();19         T3.join();20         System.out.println("T3 complete.");21     }22 }23 24 class MyThread extends Thread {25     public MyThread(String name) {26         setName(name);27     }28 29     @Override30     public void run() {31         for (int i = 0; i < 5; i++) {32             System.out.println(Thread.currentThread().getName() + ": " + i);33             try {34                 // do something...35                 Thread.sleep(100);36             } catch (InterruptedException e) {37                 e.printStackTrace();38             }39         }40     }41 }

实现需求的方案二:

public class Test2Main {    public static void main(String[] args) {        final Thread T1 = new Thread(new Runnable() {            @Override            public void run() {                System.out.println("T1...");            }        });        final Thread T2 = new Thread(new Runnable() {            @Override            public void run() {                try {                    T1.join();                }catch (InterruptedException ex){                    ex.printStackTrace();                }                System.out.println("T2...");            }        });        final Thread T3 = new Thread(new Runnable() {            @Override            public void run() {                try {                    T2.join();                }catch (InterruptedException ex){                    ex.printStackTrace();                }                System.out.println("T3...");            }        });        T3.start();        T2.start();        T1.start();    }}

实现方案三:使用ReentrantLock来解决, 还有个state整数用来判断轮到谁执行了

import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock;public class ABC {    private static Lock lock = new ReentrantLock();//通过JDK5中的锁来保证线程的访问的互斥    private static int state = 0;        static class ThreadA extends Thread {        @Override        public void run() {            for (int i = 0; i < 10;) {                lock.lock();                if (state % 3 == 0) {                    System.out.print("A");                    state++;                    i++;                }                lock.unlock();            }        }    }        static class ThreadB extends Thread {        @Override        public void run() {            for (int i = 0; i < 10;) {                lock.lock();                if (state % 3 == 1) {                    System.out.print("B");                    state++;                    i++;                }                lock.unlock();            }        }    }        static class ThreadC extends Thread {        @Override        public void run() {            for (int i = 0; i < 10;) {                lock.lock();                if (state % 3 == 2) {                    System.out.print("C");                    state++;                    i++;                }                lock.unlock();            }        }    }        public static void main(String[] args) {        new ThreadA().start();        new ThreadB().start();        new ThreadC().start();    }    }

使用lock来保证只有一个线程在输出操作, 要保证了state不会被两个线程同时修改, 思路简单

实现方案四:还可以使用condition, condition的效率可能会更高一些, await会释放lock锁, condition的await和signal与object的wait和notify方法作用类似

import java.util.concurrent.locks.Condition;import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock;public class ABC2 {    private static Lock lock = new ReentrantLock();    private static int count = 0;    private static Condition A = lock.newCondition();    private static Condition B = lock.newCondition();    private static Condition C = lock.newCondition();        static class ThreadA extends Thread {        @Override        public void run() {            lock.lock();            try {                for (int i = 0; i < 10; i++) {                    while (count % 3 != 0)                        A.await(); // 会释放lock锁                    System.out.print("A");                    count++;                    B.signal(); // 唤醒相应线程                }            } catch (InterruptedException e) {                e.printStackTrace();            } finally {                lock.unlock();            }        }            }        static class ThreadB extends Thread {        @Override        public void run() {            lock.lock();            try {                for (int i = 0; i < 10; i++) {                    while (count % 3 != 1)                        B.await();                    System.out.print("B");                    count++;                    C.signal();                }            } catch (InterruptedException e) {                e.printStackTrace();            } finally {                lock.unlock();            }        }            }        static class ThreadC extends Thread {        @Override        public void run() {            lock.lock();            try {                for (int i = 0; i < 10; i++) {                    while (count % 3 != 2)                        C.await();                    System.out.println("C");                    count++;                    A.signal();                }            } catch (InterruptedException e) {                e.printStackTrace();            } finally {                lock.unlock();            }        }            }        public static void main(String[] args) throws InterruptedException {        new ThreadA().start();        new ThreadB().start();        ThreadC threadC = new ThreadC();        threadC.start();        threadC.join();        System.out.println(count);    }}

实现方案五:使用信号量也可以, 这个思路最简单, 整个代码也比较简洁

import java.util.concurrent.Semaphore;public class ABC3 {    private static Semaphore A = new Semaphore(1);    private static Semaphore B = new Semaphore(1);    private static Semaphore C = new Semaphore(1);        static class ThreadA extends Thread {        @Override        public void run() {            try {                for (int i = 0; i < 10; i++) {                    A.acquire();                    System.out.print("A");                    B.release();                }            } catch (InterruptedException e) {                e.printStackTrace();            }        }            }        static class ThreadB extends Thread {        @Override        public void run() {            try {                for (int i = 0; i < 10; i++) {                    B.acquire();                    System.out.print("B");                    C.release();                }            } catch (InterruptedException e) {                e.printStackTrace();            }        }            }        static class ThreadC extends Thread {        @Override        public void run() {            try {                for (int i = 0; i < 10; i++) {                    C.acquire();                    System.out.println("C");                    A.release();                }            } catch (InterruptedException e) {                e.printStackTrace();            }        }            }        public static void main(String[] args) throws InterruptedException {        B.acquire(); C.acquire(); // 开始只有A可以获取, BC都不可以获取, 保证了A最先执行        new ThreadA().start();        new ThreadB().start();        new ThreadC().start();    }}

注意:

lock是需要lock所有者去释放的, 即谁lock, 谁释放, 不可以跨线程, 会报java.lang.IllegalMonitorStateException;

semaphore是没有所有者的说法, 可以跨线程释放和获取.

方案三、四、五转自《》

 

转载地址:http://lgnzx.baihongyu.com/

你可能感兴趣的文章
Receiving and Processing a SAML 2.0 Response With an HttpServlet Using OpenSAML
查看>>
BZOJ1721 Ski Lift 缆车支柱
查看>>
发现一个开源项目-Altairis Simple ASP.NET SQL Providers
查看>>
关于Socket通讯时通讯协议的制定
查看>>
HDU-1150-MachineSchedule(二分图匹配)
查看>>
PHP session 跨子域问题总结
查看>>
C#中的抽象方法,虚方法,接口之间的对比
查看>>
计算机视觉入门 Intorduction To Computer Vision
查看>>
[LeetCode] Implement Trie (Prefix Tree)
查看>>
SharedPreferences
查看>>
系统session超时时间的设置
查看>>
load
查看>>
as 快捷键
查看>>
郑捷《机器学习算法原理与编程实践》学习笔记(第六章 神经网络初步)6.2 BP神经网络...
查看>>
2_C语言中的数据类型 (九)逻辑运算符与if语句、switch、条件运算符?、goto语句与标号...
查看>>
左右相等
查看>>
linux 客户端 Socket 非阻塞connect编程
查看>>
Design Diagram
查看>>
Modernizr——为HTML5和CSS3而生!
查看>>
hdu 2852 KiKi's K-Number (线段树)
查看>>