java 多个线程按顺序交替执行

2023-12-18 12:58:20

使用Thread.join()

join主要是让父线程等待子线程结束之后父线程才能继续运行

public static void main(String[] args) throws InterruptedException {
        MyThread thread1 = new MyThread("线程1");
        thread1.start();
        thread1.join();

        MyThread thread2 = new MyThread("线程2");
        thread2.start();
        thread2.join();

        MyThread thread3 = new MyThread("线程2");
        thread3.start();
        thread3.join();

    }

    static class MyThread extends Thread {
        public MyThread(String name) {
            super(name);
        }

        @Override
        public void run() {
            super.run();
            System.out.println(Thread.currentThread().getName() + "执行了");
        }
    }

使用FutureTask

public static void main(String[] args) throws InterruptedException, Exception {
        FutureTask<String> task1 = new FutureTask<>(new MyClass());
        Thread t1 = new Thread(task1, "线程1");
        t1.start();
        System.out.println("线程1返回结果" + task1.get());

        FutureTask<String> task2 = new FutureTask<>(new MyClass());
        Thread t2 = new Thread(task2, "线程2");
        t2.start();
        System.out.println("线程2返回结果" + task2.get());

        FutureTask<String> task3 = new FutureTask<>(new MyClass());
        Thread t3 = new Thread(task3, "线程3");
        t3.start();
        System.out.println("线程3返回结果" + task3.get());
    }

    static class MyClass implements Callable<String> {
        @Override
        public String call() throws Exception {
            return Thread.currentThread().getName();
        }
    }

使用CountDownLatch

CountDownLatch使用一个计数器,调用await()方法计数器+1,调用countDown()方法计数器-1,当计数器为0时,使用await()方法的线程可以继续运行。

    private static CountDownLatch c1 = new CountDownLatch(1);
    private static CountDownLatch c2 = new CountDownLatch(1);
    public static void main(String[] args) throws InterruptedException, Exception {
        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(500);
                    System.out.println("线程1执行");
                    c1.countDown();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

            }
        }, "线程1");
        t1.start();

        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    c1.await();
                    System.out.println("线程2执行");
                    c2.countDown();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

            }
        }, "线程2");
        t2.start();

        Thread t3 = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    c2.await();
                    System.out.println("线程3执行");
                    
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

            }
        }, "线程3");
        t3.start();
    }

使用wait、notify

private static final Object lock1 = new Object();
    private static final Object lock2 = new Object();
    public static void main(String[] args) throws InterruptedException, Exception {
        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (lock1) {
                    try {
                        lock1.wait();
                        Thread.sleep(500);
                        System.out.println("线程1执行");
                        lock1.notify();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }, "线程1");
        t1.start();

        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (lock1) {
                    try {
                        lock1.notify();
                        lock1.wait();
                        System.out.println("线程2执行");
                        synchronized (lock2) {
                            lock2.notify();
                        }
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }, "线程2");
        t2.start();

        Thread t3 = new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (lock2) {
                    try {
                        lock2.wait();
                        System.out.println("线程3执行");
                        
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }


            }
        }, "线程3");
        t3.start();
    }

使用ReentrantLock()

private static Lock lock = new ReentrantLock();
    private static Condition condition1 = lock.newCondition();
    private static Condition condition2 = lock.newCondition();
    public static void main(String[] args) throws InterruptedException, Exception {
        Thread t1 = new Thread(new Runnable() {

            @Override
            public void run() {
                try {
                    lock.lock();
                    condition1.await();
                    Thread.sleep(500);
                    System.out.println("线程1执行了");
                    condition1.signal();
                    lock.unlock();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

            }
        }, "线程1");
        t1.start();

        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    lock.lock();
                    condition1.signal();
                    condition1.await();
                    System.out.println("线程2执行");
                    condition2.signal();
                    lock.unlock();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

        }, "线程2");
        t2.start();

        Thread t3 = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    lock.lock();
                    condition2.await();
                    System.out.println("线程3执行");
                    lock.unlock();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, "线程3");
        t3.start();
    }

使用线程池的单例池

private static ExecutorService executorService = Executors.newSingleThreadExecutor();
    public static void main(String[] args) throws InterruptedException, Exception {
        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                try {

                    Thread.sleep(500);
                    System.out.println("线程1执行了");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

            }
        }, "线程1");

        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(200);
                    System.out.println("线程2执行");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

        }, "线程2");

        Thread t3 = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(10);
                    System.out.println("线程3执行");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, "线程3");

        executorService.submit(t1);
        executorService.submit(t2);
        executorService.submit(t3);
    }

多线程的线程池

    private static ExecutorService executorService = Executors.newFixedThreadPool(3);
    public static void main(String[] args) throws InterruptedException, ExecutionException {
        long start = System.currentTimeMillis();
        ArrayList<Future<String>> futureList = new ArrayList<Future<String>>();
        ArrayList<String> names = new ArrayList<String>();
        for (int i = 0; i < 3; i++) {
            futureList.add(executorService.submit(new MyCall(i + "")));
        }

        for (int i = 0; i < 3; i++) {
            Future<String> future = futureList.get(i);
            String value = future.get();
            System.out.println("线程"+value+"执行了");
        }
        long spendTime = System.currentTimeMillis() - start;
        System.out.println("花费时间---"+spendTime);

    }
    
    
    static class MyCall implements Callable<String> {
        private String name;

        public MyCall(String name) {
            this.name = name;
        }

        @Override
        public String call() throws Exception {
            switch (name){
                case "0":
                    Thread.sleep(3000);
                    break;
                case "1":
                    Thread.sleep(2000);
                    break;
                case "2":
                    Thread.sleep(1000);
                    break;
            }

            return name;
        }
    }

通过wait和notify让两个线程交替打印1-100

public static void main(String[] args) throws InterruptedException {
        MyThread thread1 = new MyThread("线程1");
        MyThread thread2 = new MyThread("线程2");
        thread1.start();
        thread2.start();
    }

    static class MyThread extends Thread {
        static int num;
        static Object object = new Object();
        public MyThread(String name) {
            super(name);
        }

        @Override
        public void run() {
            while (true) {
                synchronized (object) {
                    object.notify();
                    if (num < 100) {
                        num++;
                        System.out.println(Thread.currentThread().getName() + ": " + num);
                    } else {
                        break;
                    }


                    try {
                        object.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }

使用Reentranlock实现交替打印

public static void main(String[] args) throws InterruptedException {
        MyThread thread1 = new MyThread("线程1", 0);
        MyThread thread2 = new MyThread("线程2", 1);
        thread1.start();
        thread2.start();
    }

    private static volatile int flag = 0;
    static class MyThread extends Thread {
        private static int number = 0;
        private int flag = 0;
        private static ReentrantLock lock = new ReentrantLock();
        private static Condition condition = lock.newCondition();
        public MyThread(String name, int flag) {
            super(name);
            this.flag = flag;
        }

        @Override
        public void run() {
            while (number < 100) {
                lock.lock();
                if (number >= 100) break;
                if (number % 2 == this.flag) {
                    number++;
                    System.out.println(currentThread().getName() + ":" + number);
                } else {
                    try {
                        condition.await();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }

                condition.signal();
                lock.unlock();
            }
        }
    }

使用volatile关键字实现不加锁交替打印

//两个线程,一个打印奇数,一个打印偶数
public class OneToHundred{
   static volatile int flag = 0;
   public static void main(String[] args){
      new Thread(new Task1(),"A").start();
      new Thread(new Task2(),"B").start();
   }
}
 
class Task1 implements Runnable{
   @Override
   public void run(){
     int i = -2;
     while(i<=99){
       if(OneToHundred.flag == 0){
          i+=2;
          System.out.println("a:" + i);
          OneToHundred.flag = 1;
       }
     }
   }
}
 
class Task2 implements Runnable{
   @Override
   public void run(){
     int i = -1;
     while(i<=98){
       if(OneToHundred.flag == 1){
          i+=2;
          System.out.println("b:" + i);
          OneToHundred.flag = 0;
       }
     }
   }
}

文章来源:https://blog.csdn.net/weixin_49131718/article/details/135047694
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。