`

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多线程编程技术PDF

    总结起来,“JAVA多线程编程技术PDF”涵盖了多线程的基本概念、同步机制、线程通信、死锁避免、线程池以及线程安全的集合类等内容。通过深入学习这份资料,开发者可以全面掌握Java多线程编程技术,提升程序的并发...

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

    《汪文君JAVA多线程编程实战》是一本专注于Java多线程编程的实战教程,由知名讲师汪文君倾力打造。这本书旨在帮助Java开发者深入理解和熟练掌握多线程编程技术,提升软件开发的效率和质量。在Java平台中,多线程是...

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

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

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

    Java多线程编程是Java开发中的重要组成部分,它允许程序同时执行多个任务,极大地提高了程序的效率和响应性。在Java中,多线程主要通过继承Thread类或实现Runnable接口来实现。本教程《Java多线程编程核心技术》将...

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

    《Java多线程编程实战指南》这本书深入浅出地讲解了Java多线程的核心概念和实战技巧,分为核心篇和设计模式篇,旨在帮助开发者掌握并应用多线程技术。 1. **线程基础** - **线程的创建**:Java提供了两种创建线程...

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

    《Java多线程编程实战指南-核心篇》是一本深入探讨Java并发编程的书籍,旨在帮助读者掌握在Java环境中创建、管理和同步线程的核心技术。Java的多线程能力是其强大之处,使得开发者能够在同一时间执行多个任务,提高...

    Java多线程编程

    Java多线程编程是Java开发中的重要组成部分,它允许程序同时执行多个任务,极大地提高了程序的效率和响应性。在Java中,多线程主要通过`Thread`类和并发工具来实现,接下来我们将深入探讨这些关键知识点。 1. **...

    java多线程编程

    Java多线程编程是Java开发中的重要组成部分,它允许程序同时执行多个任务,极大地提高了程序的效率和响应性。在Java中,多线程主要通过继承Thread类或实现Runnable接口来实现。本教程将深入探讨Java多线程的各个方面...

    java 多线程编程指南

    这份“Java多线程编程指南”深入探讨了这一主题,为中级到高级的Java开发者提供了宝贵的资源。 首先,多线程的基础概念是理解整个主题的关键。线程是程序执行的最小单元,每个线程都有自己的程序计数器、虚拟机栈、...

    深入学习:Java多线程编程

    《深入学习:Java多线程编程》是一本专注于Java并发技术的专业书籍,旨在帮助开发者深入理解和熟练运用Java中的多线程编程。Java多线程是Java编程中的核心部分,尤其在现代高性能应用和分布式系统中不可或缺。理解并...

    java多线程编程实例

    从给定的文件信息中,我们可以提取出关于Java多线程编程的重要知识点,涉及线程创建、线程生命周期以及线程间的同步与通信等核心概念。 ### Java多线程编程实例解析 #### 1. 创建线程的方式 在Java中,创建线程有...

    Java多线程编程实例

    总的来说,“Java多线程编程实例”这本书涵盖了Java多线程编程的各个方面,从基础概念到高级用法,包括线程创建、同步机制、线程池、线程通信以及并发工具类的使用,都是现代Java开发者必备的知识。虽然年代久远,但...

    Java多线程编程指南

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

    【JAVA多线程】多线程编程核心技术学习资料

    Java多线程编程是Java开发中的重要组成部分,它允许程序同时执行多个任务,极大地提高了程序的效率和响应性。在现代计算机系统中,多线程技术尤其关键,因为它们能够充分利用多核处理器的能力。这份"Java多线程编程...

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

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

    Java多线程编程核心技术.zip

    Java多线程编程是Java开发中的重要组成部分,它允许程序同时执行多个任务,提升系统效率。在Java中,实现多线程主要有两种方式:继承Thread类和实现Runnable接口。本资料"Java多线程编程核心技术.zip"深入探讨了这些...

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

    《Java多线程编程实例》这本书深入浅出地探讨了Java中的多线程编程,通过丰富的实例帮助读者理解和掌握这一复杂主题。随书源码提供了实际操作的机会,以便读者能够亲手实践书中的示例,加深理解。 1. **线程创建...

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

    Java多线程编程是Java开发中的重要组成部分,它允许程序同时执行多个任务,极大地提高了程序的效率和响应性。在Java中,多线程可以通过实现Runnable接口或继承Thread类来创建。下面我们将深入探讨Java多线程编程的...

Global site tag (gtag.js) - Google Analytics