详谈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线程与线程、进程与进程间通信-创新互联
文章源于:http://ybzwz.com/article/ddgcgo.html