• 线程之间的同步通信


    第一个线程循环3次,然后二个线程循环5次, 然后第三个线程循环8次, 这样执行50次。

    一: 传统的wait(),  notify(),  notifyAll()

    package com.cn.gbx;
    
    public class TheadConnection {
    	public static void main(String[] args) {
    		final Business business = new Business();
    		
    		new Thread(
    			new Runnable() {
    				@Override
    				public void run() {
    					for (int i = 1; i <= 50; ++i) {
    						business.sub1(i);
    					}
    				}
    			}
    		).start();
    		
    		new Thread(
    			new Runnable() {
    				@Override
    				public void run() {
    					for (int i = 1; i <= 50; ++i) {
    						business.sub2(i);
    					}
    				}
    			}
    		).start();
    		
    		new Thread(
    			new Runnable() {
    				@Override
    				public void run() {
    					for (int i = 1; i <= 50; ++i) {
    						business.sub3(i);
    					}
    				}
    			}
    		).start();
    	}
    }
    
    class Business{
    	private int bShould = 0;
    	
    	public synchronized void sub1(int i) {
    		System.out.println("sub1..." + bShould);
    		while (bShould != 0) {
    			try {
    				this.wait();
    			} catch (InterruptedException e) {
    				e.printStackTrace();
    			}
    		}
    		for (int j = 1; j <= 3; ++j) {
    			System.out.println(Thread.currentThread().getName() + "  sub1 Thread seq " + i + " looping " + j);
    		}
    		bShould = 1;
    		this.notifyAll(); 
    		//一定要是notifyAll()否则会出现线程阻塞, 唤醒了其余两个的一个,
    		//然后唤醒的那个不满足执行条件,然后就没有可以将其他可执行的线程激活的了而导致死锁
    	}
    	
    	public synchronized void sub2(int i) {
    		System.out.println("sub2..." + bShould);
    		while (bShould != 1) {
    			try {
    				this.wait();
    			} catch (InterruptedException e) {
    				// TODO Auto-generated catch block
    				e.printStackTrace();
    			}
    		}
    		for (int j = 1; j <= 5; ++j) {
    			System.out.println(Thread.currentThread().getName() + "   sub2 Thread seq " + i + " looping " + j);
    		}
    		bShould = 2;
    		this.notifyAll();
    	}
    	
    	public synchronized void sub3(int i) {
    		System.out.println("sub3..." + bShould);
    		while (bShould != 2) {
    			try {
    				this.wait();
    			} catch (InterruptedException e) {
    				e.printStackTrace();
    			}
    		}
    		for (int j = 1; j <= 8; ++j) {
    			System.out.println(Thread.currentThread().getName() + "   sub3 Thread seq " + i + " looping " + j);
    		}
    		bShould = 0;
    		this.notifyAll();
    	}
    }
    

      

    二:

    通过Condition实现通信:

    package com.cn.gbx;
    
    import java.util.concurrent.locks.Condition;
    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReentrantLock;
    
    public class TheadConnection {
    	public static void main(String[] args) {
    		final Business business = new Business();
    		
    		new Thread(
    			new Runnable() {
    				@Override
    				public void run() {
    					for (int i = 1; i <= 50; ++i) {
    						business.sub1(i);
    					}
    				}
    			}
    		).start();
    		
    		new Thread(
    			new Runnable() {
    				@Override
    				public void run() {
    					for (int i = 1; i <= 50; ++i) {
    						business.sub2(i);
    					}
    				}
    			}
    		).start();
    		
    		new Thread(
    			new Runnable() {
    				@Override
    				public void run() {
    					for (int i = 1; i <= 50; ++i) {
    						business.sub3(i);
    					}
    				}
    			}
    		).start();
    	}
    }
    
    class Business{
    	private int bShould = 0;
    	
    	Lock lock = new ReentrantLock();
    	Condition condition1 = lock.newCondition();
    	Condition condition2 = lock.newCondition();
    	Condition condition3 = lock.newCondition();
    	
    	public void sub1(int i) {
    		lock.lock();
    		System.out.println("sub1..." + bShould);
    		try{
    			while (bShould != 0) {
    				try {
    					condition1.await();
    				} catch (InterruptedException e) {
    					e.printStackTrace();
    				}
    			}
    			for (int j = 1; j <= 3; ++j) {
    				System.out.println(Thread.currentThread().getName() + "  sub1 Thread seq " + i + " looping " + j);
    			}
    			bShould = 1;
    			condition2.signal();
    		}finally{
    			lock.unlock();
    		}
    	}
    	
    	public void sub2(int i) {
    		lock.lock();
    		System.out.println("sub2..." + bShould);
    		try{
    			while (bShould != 1) {
    				try {
    					condition2.await();
    				} catch (InterruptedException e) {
    					e.printStackTrace();
    				}
    			}
    			for (int j = 1; j <= 5; ++j) {
    				System.out.println(Thread.currentThread().getName() + "  sub2 Thread seq " + i + " looping " + j);
    			}
    			bShould = 2;
    			condition3.signal();
    		}finally{
    			lock.unlock();
    		}
    	}
    	
    	public void sub3(int i) {
    		lock.lock();
    		System.out.println("sub3..." + bShould);
    		try{
    			while (bShould != 2) {
    				try {
    					condition3.await();
    				} catch (InterruptedException e) {
    					e.printStackTrace();
    				}
    			}
    			for (int j = 1; j <= 8; ++j) {
    				System.out.println(Thread.currentThread().getName() + "  sub2 Thread seq " + i + " looping " + j);
    			}
    			bShould = 0;
    			condition1.signal();
    		}finally{
    			lock.unlock();
    		}
    	}
    }
    

      

  • 相关阅读:
    关于连接connection reset的问题
    Redis应用场景及缓存问题
    zookeeper集群及kafka集群搭建
    使用自定义注解和切面AOP实现Java程序增强
    Shell脚本控制docker容器启动顺序
    正则表达式匹配${key}并在Java中使用
    Redis基本数据结构之ZSet
    Redis基本数据结构之Set
    Redis基本数据结构之Hash
    Redis基本数据结构之List
  • 原文地址:https://www.cnblogs.com/E-star/p/3484617.html
Copyright © 2020-2023  润新知