详谈java线程与线程、进程与进程间通信-创新互联

创新互联www.cdcxhl.cn八线动态BGP香港云服务器提供商,新人活动买多久送多久,划算不套路!

让客户满意是我们工作的目标,不断超越客户的期望值来自于我们对这个行业的热爱。我们立志把好的技术通过有效、简单的方式提供给客户,将通过不懈努力成为客户在信息化领域值得信任、有价值的长期合作伙伴,公司提供的服务项目有:域名与空间、网络空间、营销软件、网站建设、永年网站维护、网站推广。

线程与线程间通信

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

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

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(); 
    } 
  } 
 
} 

网站标题:详谈java线程与线程、进程与进程间通信-创新互联
分享URL:https://www.cdcxhl.com/article10/ddgcgo.html

成都网站建设公司_创新互联,为您提供微信小程序网站内链小程序开发网站维护静态网站搜索引擎优化

广告

声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联

网站优化排名