zoukankan      html  css  js  c++  java
  • 线程之间的同步通信

    第一个线程循环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();
    		}
    	}
    }
    

      

  • 相关阅读:
    Delphi中的钩子函数HOOK详解
    Delphi好书推荐
    Windows通知栏图标高级编程概述
    关于开机自动运行程序和自动启动服务
    如何在一个窗体中嵌入另一个窗体
    三层中如何在服务器与客户端之间传输自定义的'Record'类型数据的例子
    Delphi中的钩子函数HOOK详解
    STL(转)
    默认参数(c++)
    STL2
  • 原文地址:https://www.cnblogs.com/E-star/p/3484617.html
Copyright © 2011-2022 走看看