`

Java多线程编程#线程等待机制

阅读更多
1、最佳的模型是:生产者-消费者
package com.boonya.multithread.explain;
/** ==============================================  
 * 文件:ProducerAndConsumer.java  
 * 描述:生产者--消费者  [生产者生产了之后消费者才能消费]
 * 注:引入了等待通知(wait/notify)机制如下: 
  1、在生产者没有生产之前,通知消费者等待;在生产者生产之后,马上通知消费者消费。 
  2、在消费者消费了之后,通知生产者已经消费完,需要生产。 
 * ============================================
 */  
public class ProducerAndConsumer {

	 public static void main(String argv[]){   
		  ShareData    s = new ShareData();   
		  new Consumer(s).start();   
		  new Producer(s).start();   
		 }   

}
class ShareData{   
    
	 private char c;   
	 // 通知变量   
	 private boolean writeable = true;   
	  
	 // -------------------------------------------------------------------------    
	 // 需要注意的是:在调用wait()方法时,需要把它放到一个同步段里,否则将会出现   
	 // "java.lang.IllegalMonitorStateException: current thread not owner"的异常。   
	 // -------------------------------------------------------------------------   
	 public synchronized void setShareChar(char c){   
		 if (!writeable){   
			   try{   
			    // 未消费等待   
			    wait();   
			   }catch(InterruptedException e){}   
		}   
	     
	    this.c = c;   
	    // 标记已经生产   
	    writeable = false;   
	    // 通知消费者已经生产,可以消费   
	    notify();   
	 }   
	    
	 public synchronized char getShareChar(){   
		 if (writeable){   
			   try{   
			    // 未生产等待   
			    wait();   
			   }catch(InterruptedException e){}     
		 }   
	     // 标记已经消费   
	     writeable = true;   
	     // 通知需要生产   
	     notify();   
	     return this.c;   
	   }   
}   

   
// 生产者线程   
class Producer extends Thread{   
    
	private ShareData s;   
    
	 Producer(ShareData s){   
	  this.s = s;   
	 }   
	    
	 public void run(){   
		 for (char ch = 'A'; ch <= 'Z'; ch++){   
			   try{   
			       Thread.sleep((int)Math.random() * 400);   
			   }catch(InterruptedException e){}   
			      
			   // 生产   
			   s.setShareChar(ch);   
			   System.out.println(ch + " producer by producer.");   
			  }   
	 }   
}   
   
// 消费者线程   
class Consumer extends Thread{   
    
	private ShareData s;   
    
	 Consumer(ShareData s){   
	  this.s = s;   
	 }   
	    
	 public void run(){   
	  char ch;   
	     
	  do{   
		  try{   
			    Thread.sleep((int)Math.random() * 400);   
		}catch(InterruptedException e){}   
			   // 消费   
			   ch = s.getShareChar();   
			   System.out.println(ch + " consumer by consumer.");   
	  }while(ch != 'Z');   
	 }   
}   




2、等待程序结束
package com.boonya.multithread.explain;
/**===================================  
* 文件:LetOneThreadSleepAfterAnotherReady.java  
* 描述:等待一个线程的结束的两种方法  
* ====================================  
*/  
public class LetOneThreadSleepAfterAnotherReady {
	
	 class  MyTaskThread extends Thread{
		
		public MyTaskThread(){}

		@Override
		public void run() {
			 for (int count = 1,row = 1; row < 20; row++,count++)   
		     {   
		        for (int i = 0; i < count; i++)   
		        {   
		           System.out.print('*');   
		        }   
		        System.out.println();   
		     }   
		}
	 }
	 
	 // 第一种方法:不断查询第一个线程是否已经终止,如果没有,则让主线程睡眠一直到它终止为止   
	 // 即:while/isAlive/sleep 
	 public void Method1(){   
		MyTaskThread th1 = new MyTaskThread();   
		MyTaskThread th2 = new MyTaskThread();   
	    // 执行第一个线程   
	    th1.start();   
	    // 不断查询第一个线程的状态   
	    while(th1.isAlive()){   
	      try{   
	         Thread.sleep(100);   
	      }catch(InterruptedException e){   
	      }   
	    }   
	    //第一个线程终止,运行第二个线程   
	    th2.start();   
	  }   
	     
	  // 第二种方法:join()   
	  public void Method2(){   
		  MyTaskThread th1 = new MyTaskThread();   
		  MyTaskThread th2 = new MyTaskThread();   
		  // 执行第一个线程   
		    th1.start();   
		    try{   
		      th1.join();   
		    }catch(InterruptedException e){   
		    }   
		    // 执行第二个线程   
		    th2.start();   
	}  
	 public static void main(String[] args) {
		 LetOneThreadSleepAfterAnotherReady mythread=new LetOneThreadSleepAfterAnotherReady();
//		 mythread.Method1();
		 mythread.Method2();
	}


}

分享到:
评论
3 楼 boonya 2013-02-18  
zjuttsw 写道
zjuttsw 写道
提一点意见:
Object的wait方法(包括它的重载方法),应该始终包含在循环中。否则会造成数据不一致现象。原因是当线程调用wait方法时进入等待队列,当被其它线程唤醒时(notify or notifyAll),它会执行wait语句后面的指令。而不会再判断条件是否满足。
因此应该这样写:
public synchronized void setShareChar(char c){    
         while (!writeable){          /* 把 if 改成 while */
               try{    
                // 未消费等待    
                wait();    
               }catch(InterruptedException e){}    
        }
同理getShareChar方法也应该把if改成while。    

同时因为wait和notify的使用比较困难,容易出错。因此在JDK 1.5版本以后,不建议再使用notify和wait方法。一个更好的方法是使用Java大师(Doug Lea)编写的java.util.concurrent并行包里的API来实现。


谢谢指点!
2 楼 zjuttsw 2013-02-17  
zjuttsw 写道
提一点意见:
Object的wait方法(包括它的重载方法),应该始终包含在循环中。否则会造成数据不一致现象。原因是当线程调用wait方法时进入等待队列,当被其它线程唤醒时(notify or notifyAll),它会执行wait语句后面的指令。而不会再判断条件是否满足。
因此应该这样写:
public synchronized void setShareChar(char c){    
         while (!writeable){          /* 把 if 改成 while */
               try{    
                // 未消费等待    
                wait();    
               }catch(InterruptedException e){}    
        }
同理getShareChar方法也应该把if改成while。    

同时因为wait和notify的使用比较困难,容易出错。因此在JDK 1.5版本以后,不建议再使用notify和wait方法。一个更好的方法是使用Java大师(Doug Lea)编写的java.util.concurrent并行包里的API来实现。
1 楼 zjuttsw 2013-02-17  
提一点意见:
Object的wait方法(包括它的重载方法),应该始终包含在循环中。否则会造成数据不一致现象。原因是当线程调用wait方法时进入等待队列,当被其它线程唤醒时(notify or notifyAll),它会执行wait语句后面的指令。而不会再判断条件是否满足。
因此应该这样写:
public synchronized void setShareChar(char c){    
         while (!writeable){          /* 把 if 改成 while */
               try{    
                // 未消费等待    
                wait();    
               }catch(InterruptedException e){}    
        }
同理getShareChar方法也应该把if改成while。    

相关推荐

    Java多线程编程实战指南(核心篇)

    Java多线程编程实战指南(核心篇) 高清pdf带目录 随着现代处理器的生产工艺从提升处理器主频频率转向多核化,即在一块芯片上集成多个处理器内核(Core),多核处理器(Multicore Processor)离我们越来越近了――如今...

    JAVA多线程编程技术PDF

    JAVA多线程编程技术PDF,是最经典的那个版本,多线程的所有知识点完爆读者

    java 多线程编程实战指南(核心 + 设计模式 完整版)

    Java 高并发编程相关知识, 接下来将阅读该书, 并且进行比较详细的总结, 好记性不如烂笔头, 加油。 Java 多线程编程实战指南。

    java多线程编程

    java多线程编程,十分详细地讲解java多线程编程技术,视频教程

    Java多线程编程核心技术_完整版_java_

    详细介绍了java多线程的原理以及常用多线程编程方法及注意事项。

    Java多线程编程经验

    现在的操作系统是多任务操作系统。多线程是实现多任务的一种方式。 线程是指进程中的一个执行流程,一个进程中可以运行多个线程。...本文档提供Java多线程编程经验,方便广大Java爱好者研究学习Java多线程

    Java多线程编程技术

    《Java多线程编程核心技术》建议猿友们读两遍,因为其写得没有那么抽象,第一遍有些概念不是很理解,可以先跳过并记录起来,第一遍阅读的目的主要是了解整个架构。第二遍再慢慢品味,并贯穿全部是指点来思考,并将...

    汪文君JAVA多线程编程实战(完整不加密)

    汪文君JAVA多线程编程实战(完整不加密)。 汪文君JAVA多线程编程实战(完整不加密),连接挂了留言, 我补 java 汪文君 多线程 视频教程 实战。

    Java多线程编程实战指南 设计模式篇.rar

    Java多线程编程Java多线程编程Java多线程编程Java多线程编程Java多线程编程Java多线程编程

    Java多线程编程指南

    Java 给多线程编程提供了内置的支持。 一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。 多线程是多任务的一种特别的形式,但多线程使用了更小的资源开销。 ...

    Java多线程编程,生命游戏,用线程池.zip

    Java多线程编程,生命游戏,用线程池.zipJava多线程编程,生命游戏,用线程池.zip Java多线程编程,生命游戏,用线程池.zipJava多线程编程,生命游戏,用线程池.zip Java多线程编程,生命游戏,用线程池.zipJava多...

    JAVA多线程编程技术探讨.pdf

    JAVA多线程编程技术探讨,深入JAVA多线程编程技术的基础

    java多线程编程实例 (源程序)

    java多线程编程实例 java多线程编程实例 (源程序)

    java 多线程编程指南

    java多线程编程指南,一个比较高级和深入的java编程学习资料。

    《Java多线程编程实例》随书源码

    《Java多线程编程实例》随书源码《Java多线程编程实例》随书源码《Java多线程编程实例》随书源码

    java多线程编程实例

    java多线程编程实例

    Java多线程编程实例

    这是Java多线程编程实例一书的全部随书源码,这本书是很早的JAVA多线程编程指导书,虽然很老但是很经典,直到现在还很热,很有参考价值。

Global site tag (gtag.js) - Google Analytics