线程通信的几种方式

wait/notify

public class Main{
    public static Object object = new Object();

    public static void main(String[] args) {

        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (object){
                    for (int i = 0; i < 10; i+=2) {
                        System.out.println(i);
                        object.notify();
                        try {
                            object.wait();
                        }catch (InterruptedException ex){
                            ex.printStackTrace();
                        }
                    }
                }
            }
        }, "t1");

        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (object){
                    for (int i = 1; i < 10; i+=2) {
                        System.out.println(" "+i);
                        object.notify();
                        try{
                            object.wait();
                        }catch (InterruptedException ex){
                            ex.printStackTrace();
                        }
                    }
                }
            }
        }, "t2");

        t1.start();
        t2.start();
    }
}

ReentrantLock 结合 Condition

public class ReenTranLockTest {
    public static void main(String[] args) {
        ReentrantLock lock = new ReentrantLock();
        Condition condition = lock.newCondition();

        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                lock.lock();
                for (int i = 0; i <10 ; i+=2) {
                    System.out.println(i);
                    condition.signal();
                    try{
                        condition.await();
                    }catch (InterruptedException ex){
                        ex.printStackTrace();
                    }
                }
                lock.unlock();
            }
        }, "t1");

        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                lock.lock();
                for (int i = 1; i <10 ; i+=2) {
                    System.out.println(" " + i);
                    condition.signal();
                    try{
                        condition.await();
                    }catch (InterruptedException ex){
                        ex.printStackTrace();
                    }
                }
                lock.unlock();
            }
        }, "t2");

        t1.start();
        t2.start();
    }
}

Volatile

volatile 修饰内存可见性

public class Volatile implements Runnable {
  private static volatile Boolean flag = true;

  @Override
  public void run() {
    while (flag) {
      System.out.println(Thread.currentThread().getName() + " - 执行");
    }
    System.out.println("线程结束");
  }

  public static void main(String[] args) {
    Thread t = new Thread(new Volatile());
    t.start();
    try {
      Thread.sleep(5);
      flag = false;
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
  }
}

join

public class JoinTest {
    public static void main(String[] args) {
        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName() + "start");
                try{
                    Thread.sleep(3000);
                    System.out.println(Thread.currentThread().getName());
                }catch (InterruptedException ex){
                    ex.printStackTrace();
                }
            }
        }, "Thread1");

        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName() + "start");
                try{
                    Thread.sleep(3000);
                    System.out.println(Thread.currentThread().getName());
                }catch (InterruptedException ex){
                    ex.printStackTrace();
                }
            }
        }, "Thread2");

        t1.start();
        t2.start();

        try{
            t1.join();
            t2.join();
        }catch (InterruptedException ex){
            ex.printStackTrace();
        }
        System.out.println("over");
    }
}

CountDownLatch 闭锁

public class CountDownLatchTest {
    public static void main(String[] args) {
        try {
            countDownLatch();
        }catch (Exception ex){
            ex.printStackTrace();
        }
    }
    private static void countDownLatch() throws Exception{
        int thread = 3 ;
        long start = System.currentTimeMillis();
        final CountDownLatch countDown = new CountDownLatch(thread);
        for (int i= 0 ;i<thread ; i++){
            new Thread(new Runnable() {
                @Override
                public void run() {
                    System.out.println("thread run");
                    try {
                        Thread.sleep(2000);
                        countDown.countDown();
                        System.out.println("thread end");
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }).start();
        }
        countDown.await();
        long stop = System.currentTimeMillis();
        System.out.printf("main over total time=%d",stop-start);
    }
}

主线程会在所有线程都调用countDown方法后,才会用执行countDown.await();后面的语句

CyclicBarrier 栅栏

private static void cyclicBarrier() throws Exception {
    CyclicBarrier cyclicBarrier = new CyclicBarrier(3) ;
    new Thread(new Runnable() {
        @Override
        public void run() {
            LOGGER.info("thread run");
            try {
                cyclicBarrier.await() ;
            } catch (Exception e) {
                e.printStackTrace();
            }
            LOGGER.info("thread end do something");
        }
    }).start();
    new Thread(new Runnable() {
        @Override
        public void run() {
            LOGGER.info("thread run");
            try {
                cyclicBarrier.await() ;
            } catch (Exception e) {
                e.printStackTrace();
            }
            LOGGER.info("thread end do something");
        }
    }).start();
    new Thread(new Runnable() {
        @Override
        public void run() {
            LOGGER.info("thread run");
            try {
                Thread.sleep(5000);
                cyclicBarrier.await() ;
            } catch (Exception e) {
                e.printStackTrace();
            }
            LOGGER.info("thread end do something");
        }
    }).start();
    LOGGER.info("main thread");
}

CyclicBarrier 中文名叫做屏障或者是栅栏,也可以用于线程间通信。

和CountDownLatch的区别是,
CyclicBarrier 用于参与者线程之间的互相等待,当所有参与者线程都执行到cyclicBarrier.await()的时候,再继续往下执行
而CountDownLatch是其他未参与线程,等待参与者都执行countDown方法后,再继续往下执行。

线程响应中断

public class StopThread implements Runnable {
    @Override
    public void run() {
        while ( !Thread.currentThread().isInterrupted()) {
            // 线程执行具体逻辑
            System.out.println(Thread.currentThread().getName() + "运行中。。");
        }
        System.out.println(Thread.currentThread().getName() + "退出。。");
    }
    public static void main(String[] args) throws InterruptedException {
        Thread thread = new Thread(new StopThread(), "thread A");
        thread.start();
        System.out.println("main 线程正在运行") ;
        TimeUnit.MILLISECONDS.sleep(10) ;
        thread.interrupt();
    }
}

可以采用中断线程的方式来通信,调用了 thread.interrupt() 方法其实就是将 thread 中的一个标志属性置为了 true。

并不是说调用了该方法就可以中断线程,如果不对这个标志进行响应其实是没有什么作用(这里对这个标志进行了判断)。

也可以用公共变量标志位,来实现。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值