`

java线程之间通信<四>

    博客分类:
  • java
 
阅读更多
  
  在同步方法中,线程间的通信主要依靠wait(),notify(),notifyAall(),来实现。

   这三个方法必须在synconized 代码块中使用。
下面这段话引用网上:
引用
  wait()方法使当前线程暂停执行并释放对象锁标志,让其他线程可以进入Synchronized数据块,当前线程被放入对象等待池中。当调用 notify()方法后,将从对象的等待池中移走一个任意的线程并放到锁标志等待池中,只有锁标志等待池中的线程能够获取锁标志;如果锁标志等待池中没有线程,则notify()不起作用。
   notifyAll()则从对象等待池中移走所有等待那个对象的线程并放到锁标志等待池中


下面用代码测验:

程序主要实现2个线程之间通信,实现线程访问的对象的实例变量在0,1之间交替出现。
代码如下:


package com.xxg.Notify;

public class Model {
	
	 public int number;
	 
	public synchronized void add(){
		
		if(number!=0)
		{
		  try {
			wait();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}	
		}
		number++;

		System.out.println("【当前线程】==="+Thread.currentThread().getName()+"===="+number+"-----当前对应的对象锁为----"+this);
		notify();
		
	}
public synchronized void decrease(){
		
		if(number==0)
		{
		  try {
			wait();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}	
		}
		number--;
		
		System.out.println("【当前线程】==="+Thread.currentThread().getName()+"===="+number+"-----当前对应的对象锁为----"+this);
		notify();
		
	}
  
}




//增加变量值线程
package com.xxg.Notify;

public class ThIncrease extends Thread {
	public Model in;
	
	 public ThIncrease(Model in)
	 {
		 this.in = in;
	 }
	public void run() {
	 for(int i=0;i<10;i++)	 
	 {   
		 try {
		Thread.sleep(1000);
	} catch (InterruptedException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
		 in.add(); //调用自加方法
	 }
	 }
}

//===========================实现自减线程=========================
package com.xxg.Notify;

public class ThDecrease extends Thread {
	public Model in;
	
	 public ThDecrease(Model in)
	 {
		 this.in = in;
	 }
	public void run() {
	 for(int i=0;i<10;i++)	 
	 {   
		 try {
		Thread.sleep(1000);
	} catch (InterruptedException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
		 in.decrease();
	 }
	 }
		 
	}


//==========================测试代码=============================
package com.xxg.Notify;

public class Test {

	
	public static void main(String[] args) {
	
		Model mo = new Model();
		Model mo1 = new Model();
	
		Thread t1 = new ThDecrease(mo);
		Thread t2 = new ThIncrease(mo);
		t1.start();
		t2.start();
		
	}

}
//=========================测试结果==============================

【当前线程】===Thread-1====1-----当前对应的对象锁为----com.xxg.Notify.Model@1bc4459
【当前线程】===Thread-0====0-----当前对应的对象锁为----com.xxg.Notify.Model@1bc4459
【当前线程】===Thread-1====1-----当前对应的对象锁为----com.xxg.Notify.Model@1bc4459
【当前线程】===Thread-0====0-----当前对应的对象锁为----com.xxg.Notify.Model@1bc4459
【当前线程】===Thread-1====1-----当前对应的对象锁为----com.xxg.Notify.Model@1bc4459
【当前线程】===Thread-0====0-----当前对应的对象锁为----com.xxg.Notify.Model@1bc4459
【当前线程】===Thread-1====1-----当前对应的对象锁为----com.xxg.Notify.Model@1bc4459
【当前线程】===Thread-0====0-----当前对应的对象锁为----com.xxg.Notify.Model@1bc4459
【当前线程】===Thread-1====1-----当前对应的对象锁为----com.xxg.Notify.Model@1bc4459
【当前线程】===Thread-0====0-----当前对应的对象锁为----com.xxg.Notify.Model@1bc4459
【当前线程】===Thread-1====1-----当前对应的对象锁为----com.xxg.Notify.Model@1bc4459
【当前线程】===Thread-0====0-----当前对应的对象锁为----com.xxg.Notify.Model@1bc4459
【当前线程】===Thread-1====1-----当前对应的对象锁为----com.xxg.Notify.Model@1bc4459
【当前线程】===Thread-0====0-----当前对应的对象锁为----com.xxg.Notify.Model@1bc4459
【当前线程】===Thread-1====1-----当前对应的对象锁为----com.xxg.Notify.Model@1bc4459
【当前线程】===Thread-0====0-----当前对应的对象锁为----com.xxg.Notify.Model@1bc4459
【当前线程】===Thread-1====1-----当前对应的对象锁为----com.xxg.Notify.Model@1bc4459
【当前线程】===Thread-0====0-----当前对应的对象锁为----com.xxg.Notify.Model@1bc4459
【当前线程】===Thread-1====1-----当前对应的对象锁为----com.xxg.Notify.Model@1bc4459
【当前线程】===Thread-0====0-----当前对应的对象锁为----com.xxg.Notify.Model@1bc4459



通过wait()和notify()方法实现了线程通信,1,和0交替出现。

注意:如果把测试代码
Thread t1 = new ThDecrease(mo);
Thread t2 = new ThIncrease(mo);
改成
Thread t1 = new ThDecrease(mo);
Thread t2 = new ThIncrease(mo1);
就无法实现线程通信了,测试结果为:
【当前线程】===Thread-1====1-----当前对应的对象锁为----com.xxg.Notify.Model@1bc4459
只出现一条结果,就出现死锁了。
我的理解是这样的不知道对不,还望大神指点下。
理解:由于这里产生了mo,mo1,两个不同的对象锁,那么mo1.notif()方法是不可能去唤醒 mo.wait()等待的线程。简单的说就是不同对象的notify()和wait()方法不能互相通信。
分享到:
评论

相关推荐

    北大Java语言程序设计(ppt课件)

    &lt;br&gt; &lt;br&gt;第五讲 输入/输出处理&lt;br&gt; &lt;br&gt;第六讲 例外处理(Exception)&lt;br&gt; &lt;br&gt;第七讲 多线程 &lt;br&gt; &lt;br&gt;第八讲 图形用户界面与事件处理&lt;br&gt; &lt;br&gt;第九讲 Java Applet&lt;br&gt; &lt;br&gt;第十讲 网络通信 &lt;br&gt; &lt;br&gt;第十一讲 J2EE...

    Java案例开发锦集

    目录&lt;br&gt;第一章 Java与Applet&lt;br&gt; 案例一 图形按钮&lt;br&gt; 案例二 模拟工具条&lt;br&gt; 案例三 Applet与Applet在页内的通信&lt;br&gt; 案例四 电子相册&lt;br&gt; 案例五 百页窗效果&lt;br&gt; 案例六 波浪彩虹文字&lt;br&gt; 案例七 3D立体渐层文字...

    JSP訳文--工具--Java

    ASPer看过来&lt;br&gt;困扰JSP的一些问题:jsp和宏之间的争议&lt;br&gt;jsp的5个不足之处&lt;br&gt;JSP不能代替Servlet&lt;br&gt;Resin中的JSP范例&lt;br&gt;JSP发送邮件&lt;br&gt;jsp如何与ejb通信&lt;br&gt;Servlet和JSP的通信&lt;br&gt;jsp与applet通信&lt;br&gt;在JSP中...

    Java JDK实例宝典

    &lt;br&gt;第1章 Java基础 &lt;br&gt;1.1 转换基本数据类型 &lt;br&gt;1.2 Java的运算符 &lt;br&gt;1.3 控制程序的流程 &lt;br&gt;1.4 计算阶乘 &lt;br&gt;1.5 实现命令行程序 &lt;br&gt;第2章 Java面向对象程序设计 &lt;br&gt;2. 1 复数类 &lt;br&gt;2. 2 equals.chashCode...

    水木清华站∶Java版精华区 含jsp及js等集合.chm

    Java版精华区 &lt;br&gt;含java jsp及js等精华帖子合集&lt;br&gt;适合收藏 查询&lt;br&gt;&lt;br&gt;序号 精华区主题 &lt;br&gt;--------------------------------&lt;br&gt; 1. [目录]Java教程 &lt;br&gt; 1. [目录]Java语言教程 &lt;br&gt; 2. [目录]来自java的传说...

    mysql5.1中文手册

    目录&lt;br&gt;&lt;br&gt;前言&lt;br&gt;1. 一般信息&lt;br&gt;1.1. 关于本手册&lt;br&gt;1.2. 本手册采用的惯例&lt;br&gt;1.3. MySQL AB概述&lt;br&gt;1.4. MySQL数据库管理系统概述&lt;br&gt;1.4.1. MySQL的历史&lt;br&gt;1.4.2. MySQL的的主要特性&lt;br&gt;1.4.3. MySQL稳定性...

    java多线程通信图解

    java 多线程 其实就是每个线程都拥有自己的内存空间,多线程之间的通信,比例A线程修改了主内存(main方法的线程)变量,需要把A线程修改的结果同步到主线程中,这时B线程再从主线程获取该变量的值,这样就实现了...

    JAVA线程简介(多线程)

    本教程研究了线程的基础知识 — 线程是什么、线程为什么有用以及怎么开始编写... &lt;br&gt;&lt;br&gt;我们还将研究更复杂的、使用线程的应用程序的基本构件 — 如何在线程之间交换数据、如何控制线程以及线程如何互相通信。 &lt;br&gt;

    JAVA网络编程:第1章 课程介绍.ppt

    HTML文档由全局架构标签如&lt;html&gt;、&lt;head&gt;、&lt;title&gt;和&lt;body&gt;构建,还包括各种其他标签,如文本标签&lt;h1&gt;到&lt;h6&gt;、&lt;b&gt;、&lt;i&gt;,超链接标签&lt;a&gt;,图像标签&lt;img&gt;,表格标签&lt;table&gt;、&lt;tr&gt;、&lt;td&gt;、&lt;th&gt;,以及表单元素&lt;form&gt;、...

    Java 线程通信示例 源代码

    这个"Java线程通信示例源代码"很可能包含了演示如何在不同线程之间共享数据和协调执行顺序的实例。线程通信主要涉及两个核心概念:同步和互斥。 1. **线程同步**:线程同步是为了防止多个线程同时访问共享资源,...

    java模拟数据库事务

    用java来模拟事务间的并发处理&lt;br&gt;后台是用文件存储来模拟数据库数据&lt;br&gt;用到的技术有:&lt;br&gt;1) java Socket通信&lt;br&gt;2) java多线程缓冲&lt;br&gt;3) 各重java设计模式&lt;br&gt;

    Java 线程间通信,生产者与消费者模型

    使用wait()和notify()实现的生产者与消费者模型,可以了解如何使用wait()和notify()进行线程间通信。(上一次上传的代码有一个问题没有考虑到,这次修补了——CSDN没法撤销资源,只能再上传了)

    socket线程连接池实例

    本实例探讨的是如何利用Java中的Socket对象以及线程连接池技术,特别是`GenericObjectPool`来提高程序性能和效率。首先,我们需要理解Socket和线程连接池的基本概念。 **Socket**: Socket是网络通信的一种接口,它...

    Java连接mongoDB需要的jar包(3.9.1)

    3. `mongodb-driver-core-3.9.1.jar`: 这个核心库包含了基本的网络通信和线程管理功能,是MongoDB Java驱动的基础。它负责处理与MongoDB服务器的低级别交互,比如TCP连接、心跳检测和数据流的序列化/反序列化。这个...

    Java线程间的通信----生产者消费者模型

    BlockingQueue&lt;Integer&gt; queue = new LinkedBlockingQueue&lt;&gt;(10); new Thread(new Producer(queue)).start(); new Thread(new Consumer(queue)).start(); } } ``` 这段代码创建了一个容量为10的`...

    JSP技术基础习题.pdf

    * 文档头信息包含在&lt;head&gt;与&lt;/head&gt;之间。 * 文档体包含在&lt;body&gt;和&lt;/body&gt;标记之间。 HTML 样式 * 可以使用 bgcolor 属性设置文档体背景颜色。 * 可以使用 text、bgcolor、background 等属性设置文本样式。 * 可以...

    java线程同步及通信

    Java线程同步与通信是多线程编程中的关键概念,用于解决并发访问共享资源时可能出现的数据不一致性和竞态条件问题。以下将详细介绍这两个主题,以及如何通过代码示例进行演示。 1. **线程同步**: 线程同步是确保...

    Java多线程通信机制研究.pdf

    Java多线程通信机制是Java程序设计中的一个复杂技术,涉及到多个线程之间的通信和协作。多线程是一种程序运行机制,它允许在程序中并发执行多个指令流,每个指令流都被称为一个线程,彼此间互相独立。 多线程之间的...

    Java的多线程-线程间的通信.doc

    线程的状态转换是理解线程通信的基础,主要包括四个状态:新(New)、可执行(Runnable)、死亡(Dead)和停滞(Blocked)。新状态是指线程对象已创建但未启动;可执行状态意味着线程可能在等待CPU资源或正在执行;...

    Java多线程实现异步调用实例

    标签“多线程”强调了Java并发编程的核心概念,如线程的创建、同步、通信和状态管理。例如,`synchronized`关键字用于确保对共享资源的互斥访问,防止数据竞争;`wait()`, `notify()`和`notifyAll()`方法用于线程间...

Global site tag (gtag.js) - Google Analytics