zoukankan      html  css  js  c++  java
  • Java线程通讯方式

    线程间通信常用方式如下:

    l  休眠唤醒方式:

    Object的wait、notify、notifyAll

    Condition的await、signal、signalAll

    l  CountDownLatch:用于某个线程A等待若干个其他线程执行完之后,它才执行

    l  CyclicBarrier:一组线程等待至某个状态之后再全部同时执行

    l  Semaphore:用于控制对某组资源的访问权限

    Object的wait、notify、notifyAll

    public class WaitNotifyRunnable{
        private Object obj = new Object();
        private Integer i=0;
        public void odd() {
            while(i<10){
                synchronized (obj){
                    if(i%2 == 1){
                        System.out.println("奇数:"+i);
     i++;
                        obj.notify();
                    } else {
                        try {
                            obj.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }
    

      

    public void even(){
            while(i<10){
                synchronized (obj){
                    if(i%2 == 0){
                        System.out.println("偶数:"+i);
                        i++;
                        obj.notify();
                    } else {
                        try {
                            obj.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
    }
                }
            }
        }
        public static void main(String[] args){
            final WaitNotifyRunnable runnable = new WaitNotifyRunnable();
            Thread t1 = new Thread(new Runnable() {
                public void run() {
                    runnable.odd();
                }
            }, "偶数线程");
            Thread t2 = new Thread(new Runnable() {
    public void run() {
                    runnable.even();
                }
            }, "奇数线程");
    
            t1.start();
            t2.start();
        }
    }
    

      Condition的await、signal、signalAll

    import java.util.concurrent.locks.Condition;
    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReentrantLock;
    
    public class WaitNotifyRunnable{
        private Lock lock = new ReentrantLock();
        private Condition condition = lock.newCondition();
        private Integer i=0;
        public void odd() {
            while(i<10){
                lock.lock();
     try{
                    if(i%2 == 1){
                        System.out.println("奇数:"+i);
                        i++;
                        condition.signal();
                    } else {
                        condition.await();
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    lock.unlock();
                }
    
            }
        }
    
        public void even(){
            while(i<10){
                lock.lock();
                try{
                    if(i%2 == 0){
                        System.out.println("偶数:"+i);
                        i++;
                        condition.signal();
                    } else {
     condition.await();
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    lock.unlock();
                }
    
            }
        }
        public static void main(String[] args){
            final WaitNotifyRunnable runnable = new WaitNotifyRunnable();
     Thread t1 = new Thread(new Runnable() {
                public void run() {
                    runnable.odd();
                }
            }, "偶数线程");
            Thread t2 = new Thread(new Runnable() {
                public void run() {
                    runnable.even();
                }
            }, "奇数线程");
    
            t1.start();
            t2.start();
        }
    }
    

      

    Object和Condition休眠唤醒区别

    l  object wait()必须在synchronized(同步锁)下使用,

    l  object wait()必须要通过Nodify()方法进行唤醒

    l  condition await() 必须和Lock(互斥锁/共享锁)配合使用

    l  condition await() 必须通过 signal() 方法进行唤醒

      CountDownLatch方式

    CountDownLatch这个类能够使一个线程等待其他线程完成各自的工作后再执行。

    CountDownLatch是通过一个计数器来实现的,计数器的初始值为线程的数量

     每当一个线程完成了自己的任务后,计数器的值就会减1。当计数器值到达0时,它表示所有的线程已经完成了任务,然后在闭锁上等待的线程就可以恢复执行任务

    import java.util.concurrent.CountDownLatch;
    
    public class CoachRecerDemo {
    	private CountDownLatch countDownLatch=new CountDownLatch(3); //设置要等待的运动员
    	//运动员方法
    	public void racer(){
    		//获取线程名
    		String name=Thread.currentThread().getName();
    		System.out.println(name+"正在准备....");
    		try {
    			Thread.sleep(1000);
    		} catch (InterruptedException e) {
    			e.printStackTrace();
    		}
    		System.out.println(name+"准备完毕");
    		countDownLatch.countDown();//-1
    	}
    	//教练方法
    	public void coach(){
    		String name=Thread.currentThread().getName();
    		System.out.println(name+"等待运动员准备...");
    		try {
    			countDownLatch.await();
    		} catch (InterruptedException e) {
    			e.printStackTrace();
    		}
    		System.out.println("所有运动员就绪,"+name+"开始训练");
    	}
    
    	public static void main(String[] args) {
    		//1.创建CoachRecerDemo 实例
    		CoachRecerDemo coachRecerDemo=new CoachRecerDemo();
    		//2.创建三个线程对象
    		Thread thread1=new Thread(new Runnable(){
    			public void run() {
    				coachRecerDemo.racer();
    			}
    		},"运动员1");
    		
    		Thread thread2=new Thread(new Runnable() {
    			public void run() {
    				coachRecerDemo.racer();
    			}
    		},"运动员2");
    		
    		Thread thread3=new Thread(new Runnable() {
    			public void run() {
    				coachRecerDemo.racer();
    			}
    		},"运动员3");
    		
    		//3.教练
    		Thread thread4=new Thread(new Runnable() {
    			public void run() {
    				coachRecerDemo.coach();
    				
    			}
    		},"教练");
    		
    		thread4.start();
    		thread1.start();
    		thread2.start();
    		thread3.start();
    	}
    }
    

       CyclicBarrier方式

    CyclicBarrier是在java1.5被引入的,存在于java.util.concurrent包下。

    CyclicBarrier实现让一组线程等待至某个状态之后再全部同时执行。

    CyclicBarrier底层是三个线程同时启动

    import java.util.Date;
    import java.util.concurrent.BrokenBarrierException;
    import java.util.concurrent.CyclicBarrier;
    
    public class ThreeThreadStartDemo {
    	private CyclicBarrier cyclicBarrier = new CyclicBarrier(3);// 所有参与启动的线程数
    
    	public void startThread() {
    		// 打印线程准备启动
    		String name = Thread.currentThread().getName();
    		System.out.println(name + "正在准备...");
    
    		// 2.调用CyclicBarriar的await方法等待线程准备完毕
    		try {
    			cyclicBarrier.await();
    		} catch (InterruptedException | BrokenBarrierException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    
    		// 3.打印线程启动信息
    		System.out.println(name + "已经启动完毕" + new Date().getTime());
    
    	}
    
    	public static void main(String[] args) {
    		final ThreeThreadStartDemo threadStartDemo = new ThreeThreadStartDemo();
    		Thread thread1 = new Thread(new Runnable() {
    			public void run() {
    
    				threadStartDemo.startThread();
    			}
    		});
    		Thread thread2 = new Thread(new Runnable() {
    			public void run() {
    
    				threadStartDemo.startThread();
    			}
    		});
    		Thread thread3 = new Thread(new Runnable() {
    			public void run() {
    
    				threadStartDemo.startThread();
    			}
    		});
    		
    		thread1.start();
    		thread2.start();
    		thread3.start();
    	}	
    }
    

      Semaphore方式

    Semaphore是在java1.5被引入的,存在于java.util.concurrent包下。

    Semaphore用于控制对某组资源的访问权限。

    import java.util.concurrent.Semaphore;
    
    public class WorkerMachineDemo {
    	static class Work implements Runnable {
    		private int workerNum;
    		private Semaphore semaphore;
    
    		public Work(int workerNum, Semaphore semaphore) {
    			this.workerNum = workerNum;
    			this.semaphore = semaphore;
    		}
    
    		public void run() {
    			// 1.获取机器
    			// 2.打印工人获取到机器,开始工作
    			// 3.线程睡眠1000毫秒
    			// 4.使用完毕
    			try {
    				semaphore.acquire();
    				String name = Thread.currentThread().getName();
    				System.out.println(name + "获取到机器,开始工作");
    				Thread.sleep(1000);
    				semaphore.release();
    				System.out.println(name + "使用完毕,释放机器!");
    			} catch (Exception e) {
    				// TODO: handle exception
    			}
    		
    		}
    	}
    
    	public static void main(String[] args) {
    		int works = 8;
    		Semaphore semaphore = new Semaphore(3);// 机器数
    		for (int i = 0; i < works; i++) {
    
    			new Thread(new Work(i, semaphore)).start();
    		}
    
    	}
    }
    

      sleep和wait区别:

      wait和notify区别

    wait和notify都是Object中的方法

    wait和notify执行前线程都必须获得对象锁

    wait的作用是使当前线程进行等待

    notify的作用是通知其他等待当前线程的对象锁的线程

  • 相关阅读:
    智能推荐算法演变及学习笔记(三):CTR预估模型综述
    从中国农业银行“雅典娜杯”数据挖掘大赛看金融行业数据分析与建模方法
    智能推荐算法演变及学习笔记(二):基于图模型的智能推荐(含知识图谱/图神经网络)
    (设计模式专题3)模板方法模式
    (设计模式专题2)策略模式
    (设计模式专题1)为什么要使用设计模式?
    关于macOS上常用操作命令(持续更新)
    记录下关于RabbitMQ常用知识点(持续更新)
    EMERGENCY! EUREKA MAY BE INCORRECTLY CLAIMING INSTANCES ARE UP WHEN THEY'RE NOT. RENEWALS ARE LESSER THAN THRESHOLD AND HENCE THE INSTANCES ARE NOT BEING EXPIRED JUST TO BE SAFE.
    SpringCloud教程二:Ribbon(Finchley版)
  • 原文地址:https://www.cnblogs.com/sunliyuan/p/12188289.html
Copyright © 2011-2022 走看看