指定线程运行顺序的几种方式~

1、使用semaphore对象

public class ThreadCommunication {
    private static int num;
    /**
     * semaphore :信号对象,可在线程中阻塞多个线程,释放多个线程,线程的释放是通过permit来完成的
     * semaphore.acquire()来释放线程,若semaphore中没有permit,则阻塞等待有permit为止
     * semaphore.release(int permits) ===>release()方法用于释放多个permit信号
     */

    private static Semaphore semaphore = new Semaphore(0);

    public static void main(String[] args) {
        final Thread threadA = new Thread(new Runnable() {
            public void run() {
                try {
                    Thread.sleep(1000);
                    num = 1;
                    //初始化完成后,释放两个permit
                    semaphore.release(2);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

        Thread threadB = new Thread(new Runnable() {
            public void run() {
                try {
                    Thread.sleep(1000);
                    //semaphore 获取permit,若semaphore对象中没有permit,则会发生阻塞并等待到有permit为止
                    semaphore.acquire();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + ":获取到了类成员变量" + (num++));
            }
        });

        Thread threadC = new Thread(new Runnable() {
            public void run() {
                try {
                    Thread.sleep(1000);
                    semaphore.acquire();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + "获取到了ThreadB修改的num值: " + num);
            }
        });
//      同时开启线程
        threadA.start();
        threadB.start();
        threadC.start();
    }
}

2 、使用线程内部的join()方法

public class ThreadCommunication2 {
    private static int num;

    public static void main(String[] args) throws InterruptedException {
        Thread threadA = new Thread(new Runnable() {
            public void run() {
                try {
                    Thread.sleep(1000);
                    //完成类成员变量的赋值
                    num = 1;
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        Thread threadB = new Thread(new Runnable() {
            public void run() {
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName()+":获得了类成员变量(0为失败)"+(num++));
            }
        });
        Thread threadC = new Thread(new Runnable() {
            public void run() {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName()+":获得修改后的类成员变量"+num);
            }
        });

//        同时开启三个线程
        threadA.start();
        threadA.join();  //wait for this thread to die
        threadB.start();
        threadB.join();
        threadC.start();
    }
}

3 、使用线程池技术Executors.newSingleThreadExecutor()方法

public class ThreadCommunication3 {
    private static int num;

    public static void main(String[] args) throws InterruptedException {
        Thread threadA = new Thread(new Runnable() {
            public void run() {
                try {
                    Thread.sleep(1000);
                    //完成类成员变量的赋值
                    num = 1;
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        Thread threadB = new Thread(new Runnable() {
            public void run() {
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName()+":获得了类成员变量(0为失败)"+(num++));
            }
        });
        Thread threadC = new Thread(new Runnable() {
            public void run() {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName()+":获得修改后的类成员变量"+num);
            }
        });

        ExecutorService pool = Executors.newSingleThreadExecutor();
//        同时开启三个线程
        pool.execute(threadA);
        pool.execute(threadB);
        pool.execute(threadC);
    }
}


4、使用线程间的通讯(一)

* 模拟三个线程,A||B||C A用来初始化成员变量,供B和C使用
 * 实现:使用的是线程之间的通讯wait()和notify()方法
 * 上述两种方法要通过同步锁实现,线程之间的通讯也需要同一把锁
 */
public class ThreadCommunication4 {
    private static int num;
    private static boolean flag = false;

    public static void main(String[] args) {
        final Object obj = new Object();
        Thread threadA = new Thread(new Runnable() {
            public void run() {
                synchronized (obj) {
                    while (flag) {
                        try {
                            obj.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    try {
                        Thread.sleep(1000);
                        num = 1;
                        System.out.println("num完成初始化");
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    } finally {
                        flag = true;
                        obj.notify();
                    }
                }
            }
        });

        Thread threadB = new Thread(new Runnable() {
            public void run() {
                synchronized (obj) {
                    while (!flag) {
                        try {
                            obj.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    } finally {
                        obj.notify();
                    }
                    System.out.println(Thread.currentThread().getName() + ":获取到了类成员变量(ThreadB)" + (num++));
                }
            }
        });

        Thread threadC = new Thread(new Runnable() {
            public void run() {
                synchronized (obj) {
                    while (!flag) {
                        try {
                            obj.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    } finally {
                        obj.notify();
                    }
                    System.out.println(Thread.currentThread().getName() + "(ThreadC)获取到了的num值: " + num);
                }
            }
        });
//      同时开启线程
        threadA.start();
        threadB.start();
        threadC.start();
    }
}

5 、使用线程间的通讯方式(二)

* 模拟三个线程,A||B||C A用来初始化成员变量,供B和C使用
 * 实现:使用await()和signal()  代替synchronize()同步锁
 */
public class ThreadCommunication5 {
    private static int num;
//    private static boolean flag = false;

    public static void main(String[] args) {
        final ReentrantLock lock = new ReentrantLock();
        final Condition c1 = lock.newCondition();
        final Condition c2 = lock.newCondition();
        Thread threadA = new Thread(new Runnable() {
            public void run() {
                lock.lock();
                try {
                    c1.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                try {
                    Thread.sleep(1000);
                    num = 1;
                    System.out.println("num完成初始化");

                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    c2.signalAll();
                    lock.unlock();
                }
            }
        });

        Thread threadB = new Thread(new Runnable() {
            public void run() {
                lock.lock();
                c1.signal();
                try {
                    c2.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    c2.signalAll();
                    lock.unlock();
                }
                for (int i = 0; i < 10; i++) {
                    System.out.println(Thread.currentThread().getName() + "====" + i);
                }
                System.out.println(Thread.currentThread().getName() + ":获取到了类成员变量(ThreadB)" + (num++));
            }
        });

        Thread threadC = new Thread(new Runnable() {
            public void run() {
                lock.lock();
                c1.signal();
                try {
                    c2.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    c2.signalAll();
                    lock.unlock();
                }
                for (int i = 0; i < 10; i++) {
                    System.out.println(Thread.currentThread().getName() + "====" + i);
                }
                System.out.println(Thread.currentThread().getName() + "(ThreadC)获取到了的num值: " + num);
            }
        });
//      同时开启线程
        threadA.start();
        threadB.start();
        threadC.start();
    }
}

你可能感兴趣的:(指定线程运行顺序的几种方式~)