• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >Java > 详谈java线程与线程、进程与进程间通信

详谈java线程与线程、进程与进程间通信

作者: 字体:[增加 减小] 来源:互联网 时间:2017-05-28

通过本文主要向大家介绍了进程间通信,linux进程间通信,android 进程间通信,c#进程间通信,java进程间通信等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

线程与线程间通信

一、基本概念以及线程与进程之间的区别联系:

关于进程和线程,首先从定义上理解就有所不同

1、进程是什么?

是具有一定独立功能的程序、它是系统进行资源分配和调度的一个独立单位,重点在系统调度和单独的单位,也就是说进程是可以独 立运行的一段程序。

2、线程又是什么?

线程进程的一个实体,是CPU调度和分派的基本单位,他是比进程更小的能独立运行的基本单位,线程自己基本上不拥有系统资源。

在运行时,只是暂用一些计数器、寄存器和栈 。

他们之间的关系

1、一个线程只能属于一个进程,而一个进程可以有多个线程,但至少有一个线程(通常说的主线程)。

2、资源分配给进程,同一进程的所有线程共享该进程的所有资源。

3、线程在执行过程中,需要协作同步。不同进程的线程间要利用消息通信的办法实现同步。

4、处理机分给线程,即真正在处理机上运行的是线程。

5、线程是指进程内的一个执行单元,也是进程内的可调度实体。

从三个角度来剖析二者之间的区别

1、调度:线程作为调度和分配的基本单位,进程作为拥有资源的基本单位。

2、并发性:不仅进程之间可以并发执行,同一个进程的多个线程之间也可以并发执行。

3、拥有资源:进程是拥有资源的一个独立单位,线程不拥有系统资源,但可以访问隶属于进程的资源。.

二、多线程间通信方式:

1、共享变量

2、wait/notify机制

3、Lock/Condition机制

4、管道

三、共享变量

线程间发送信号的一个简单方式是在共享对象的变量里设置信号值。线程A在一个同步块里设置boolean型成员变量hasDataToProcess为true,线程B也在同步块里读取hasDataToProcess这个成员变量。这个简单的例子使用了一个持有信号的对象,并提供了set和check方法:


public class MySignal{

 protected boolean hasDataToProcess = false;

 public synchronized boolean hasDataToProcess(){
  return this.hasDataToProcess;
 }

 public synchronized void setHasDataToProcess(boolean hasData){
  this.hasDataToProcess = hasData;
 }

}

线程A和B必须获得指向一个MySignal共享实例的引用,以便进行通信。如果它们持有的引用指向不同的MySingal实例,那么彼此将不能检测到对方的信号。需要处理的数据可以存放在一个共享缓存区里,它和MySignal实例是分开存放的。

四、wait()/notify机制

为了实现线程通信,我们可以使用Object类提供的wait()、notify()、notifyAll()三个方法。调用wait()方法会释放对该同步监视器的锁定。这三个方法必须由同步监视器对象来调用,这可分成两种情况:

•对于使用synchronized修饰的同步方法,因为该类的默认实例是(this)就是同步监视器,所以可以直接调用这三使用个方法。

•对于synchronized修饰的同步代码块,同步监视器是synchronized括号里的对象,所以必须使用该对象调用这三个方法。

假设系统中有两条线程,这两条线程分别代表取钱者和存钱者。现在系统有一种特殊的要求,系统要求存款者和取钱者不断的实现存款和取钱动作,而且要求每当存款者将钱存入指定账户后,取钱者立即将钱取走.不允许存款者两次存钱,也不允许取钱者两次取钱。

我们通过设置一个旗标来标识账户中是否已有存款,有就为true,没有就标为false。具体代码如下:

首先我们定义一个Account类,这个类中有取钱和存钱的两个方法,由于这两个方法可能需要并发的执行取钱、存钱操作,所有将这两个方法都修改为同步方法.(使用synchronized关键字)。

public class Account { 
  private String accountNo; 
  private double balance; 
  //标识账户中是否有存款的旗标 
  private boolean flag=false; 
   
  public Account() { 
    super(); 
  } 
 
  public Account(String accountNo, double balance) { 
    super(); 
    this.accountNo = accountNo; 
    this.balance = balance; 
  }  
   
  public synchronized void draw (double drawAmount){ 
     
    try { 
       if(!flag){ 
       this.wait(); 
       }else { 
         //取钱 
         System.out.println(Thread.currentThread().getName()+" 取钱:"+drawAmount); 
         balance=balance-drawAmount; 
         System.out.println("余额 : "+balance); 
         //将标识账户是否已有存款的标志设为false 
         flag=false; 
         //唤醒其它线程 
         this.notifyAll();     
       } 
      } catch (Exception e) { 
        e.printStackTrace(); 
    } 
  } 
   
   
  public synchronized void deposit(double depositAmount){ 
   try { 
       if(flag){ 
        this.wait(); 
       } 
       else{ 
         System.out.println(Thread.currentThread().getName()+"存钱"+depositAmount); 
         balance=balance+depositAmount; 
         System.out.println("账户余额为:"+balance); 
         flag=true; 
         //唤醒其它线程 
         this.notifyAll(); 
       } 
    } catch (Exception e) { 
      // TODO: handle exception 
      e.printStackTrace(); 
    } 
  } 
 
} 
</div>

接下来创建两个线程类,分别为取钱和存钱线程!

取钱线程类:

public class DrawThread implements Runnable { 
 
  private Account account; 
  private double drawAmount; 
   
   
  public DrawThread(Account account, double drawAmount) { 
    super(); 
    this.account = account; 
    this.drawAmount = drawAmount; 
  } 
 
  public void run() { 
    for(int i=0;i<100;i++){ 
     account.draw(drawAmount);   
    } 
  } 
} 
</div>

存钱线程类:

public class depositThread implements Runnable{ 
  private Account account; 
  private double depositAmount; 
    
  public depositThread(Account account, double depositAmount) { 
    super(); 
    this.account = account; 
    this.depositAmount = depositAmount; 
  } 
 
 
  public void run() { 
  for(int i=0;i<100;i++){ 
     account.deposit(depositAmount); 
   } 
  } 
 
} 
</div>

最后我们测试一下这个取钱和存钱的操作

public class TestDraw { 
 
  public static void main(String[] args) { 
    //创建一个账户 
    Account account=new Account(); 
    new Thread(new DrawThread(account, 800),"取钱者").start(); 
    new Thread(new depositThread(account, 800),"存款者甲").start(); 
    new Thread(new depositThread(account, 800),"存款者乙").start(); 
    new Thread(new depositThread(account, 800),"存款者丙").start(); 
 
  } 
 
} 
</div>

大致的输出结果:

存款者甲存钱800.0 
账户余额为:800.0 
取钱者 取钱:800.0 
余额 : 0.0 
存款者丙存钱800.0 
账户余额为:800.0 
取钱者 取钱:800.0 
余额 : 0.0 
存款者甲存钱800.0 
账户余额为:800.0 
取钱者 取钱:800.0 
余额 : 0.0 
存款者丙存钱800.0 
账户余额为:800.0 
取钱者 取钱:800.0 
余额 : 0.0 
存款者甲存钱800.0 
账户余额为:800.0 
取钱者 取钱:800.0 
余额 : 0.0 
存款者丙存钱800.0 
账户余额为:800.0 
取钱者 取钱:800.0 
余额 : 0.0 
存款者甲存钱800.0 
账户余额为:800.0 
取钱者 取钱:800.0 
余额 : 0.0 
存款者丙存钱800.0 
账户余额为:800.0 
取钱者 取钱:800.0 
余额 : 0.0 
存款者甲存钱800.0 
账户余额为:800.0 
取钱者 取钱:800.0 
余额 : 0.0 
</div>

五、Lock/Condition机制

如何程序不使用synchronized关键字来保持同步,而是直接适用Lock对像来保持同步,则系统中不存在隐式的同步监视器对象,也就不能使用wait()、notify()、notifyAll()来协调线程的运行.

当使用LOCK对象保持同步时,JAVA为我们提供了Condition类来协调线程的运行。关于Condi

分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • 详谈java线程与线程、进程与进程间通信
  • 详谈java线程与线程、进程与进程间通信

相关文章

  • 2017-05-28java Socket实现简单模拟HTTP服务器
  • 2017-05-28java统计汉字字数的方法示例
  • 2017-05-28查看import的类是出自哪个jar包的方法
  • 2017-05-28Java字符编码原理(动力节点Java学院整理)
  • 2017-05-28MyBatis简介与配置MyBatis+Spring+MySql的方法
  • 2017-05-28springboot整合quartz实现定时任务示例
  • 2017-05-28Java语言实现简单FTP软件 FTP软件效果图预览之下载功能(2)
  • 2017-05-28关于Java变量的声明、内存分配及初始化详解
  • 2017-05-28Java 选择排序、插入排序、希尔算法实例详解
  • 2017-05-28java中将一个List等分成n个list的工具方法(推荐)

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • java 基础教程之多线程详解及简单实例
    • 实例详解java Struts2的配置与简单案例
    • spring框架下websocket的搭建
    • Java使用join方法暂停当前线程
    • Spring AOP 自定义注解的实现代码
    • 微信开发准备第一步 Maven仓库管理新建WEB项目
    • 详解Spring+Hiernate整合
    • java 获取用户的MAC地址多种方法实例详解
    • Java System类详解_动力节点Java学院整理
    • Java生产者和消费者例子_动力节点Java学院整理

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有