java多线程的等待唤醒机制及如何解决同步过程中的安全问题

/*
class Person{
   String name;
   String sex;
   boolean flag = true;
   public void setPerson(String name, String sex){
				 this.sex=sex;
				 this.name=name;
   }
}
class Input implements Runnable{
   int x=0;
   Person p;
   Input(Person p){
      this.p=p;
   }
   public void run(){
       while(true){
		   if(x==1){
			  p.setPerson("hjz", "man");
		   }
		   else p.setPerson("哈哈哈", "女女女女");
		   x=(x+1)%2;
	   }
   }
}

class Output implements Runnable{
   int x=0;
   Person p;
   Output(Person p){
      this.p=p;
   }
   public void run(){
       while(true){
	       System.out.println(p.name + "....." + p.sex);
	   }
   }
}
public class Test{
    public static void main(String[] args){
	     Person p = new Person();
		 new Thread(new Input(p)).start();
		 new Thread(new Output(p)).start();
	}
}
*/

/*
输出的结果:
哈哈哈.....man
hjz.....man
hjz.....man
哈哈哈.....man
hjz.....女女女女
*/

//线程安全隐患出现:首先考虑到是多线程操作了同一资源,所以要用同步!
/*
class Person{
   String name;
   String sex;
   boolean flag = true;
   public void setPerson(String name, String sex){
				 this.sex=sex;
				 this.name=name;
   }
}

class Input implements Runnable{
   int x=0;
   Person p;
   Input(Person p){
      this.p=p;
   }
   public void run(){
       while(true){
	      synchronized(new Object()){
			   if(x==1){
				  p.setPerson("hjz", "man");
			   }
			   else p.setPerson("哈哈哈", "女女女女");
			   x=(x+1)%2;
		  }
	   }
   }
}

class Output implements Runnable{
   int x=0;
   Person p;
   Output(Person p){
      this.p=p;
   }
   public void run(){
       while(true){
	       System.out.println(p.name + "....." + p.sex);
	   }
   }
}
public class Test{
    public static void main(String[] args){
	     Person p = new Person();
		 new Thread(new Input(p)).start();
		 new Thread(new Output(p)).start();
	}
}
 */

//同步完成之后,发现还是出现安全隐患的情况,在考虑一下是否访问统一资源的多个线程用的是同一个锁!
//本例中的应将输入输出一起同步(注意输入输出不在同一个线程之中,输出线程不会获得 Person p对象的控制权!)
/*   class Input implements Runnable{
   int x=0;
   Person p;

   Input(Person p){
      this.p=p;
   }
   public void run(){
       while(true){
	      synchronized(p){
		       if(p.flag){
			     try{
					 p.wait();
				   }catch(InterruptedException e){
				   }
			   }
		       if(!p.flag){
				   if(x==1){
					  p.setPerson("hjz", "man");
				   }
				   else p.setPerson("哈哈哈", "女女女女");
				   x=(x+1)%2;
			   }

			   p.flag=true;
			   p.notify();

		  }
	   }
   }
} */

//现在的代码是将同步放到函数里!真正开发过的时候就是这样实现,也就是我们多个线程同事操作一个类对象
//调用该类提供的对外方法,并将调用的方法进行同步!防止安全隐患!
class Person{
   String name;
   String sex;
   boolean flag = true;
   public void setPerson(String name, String sex){
       synchronized(this){
	     if(!flag){
		     try{
			    wait();
			 }catch(InterruptedException e){}
		 }
	     if(flag){
				 this.sex=sex;
				 try{
					Thread.sleep(100);
				 }catch(InterruptedException e){}
				 this.name=name;
	     }
		 flag=false;
		 notify();
	   }
   }

   public void outPerson(){
      synchronized(this){
	      if(flag){
		     try{
			     wait();
			 }catch(InterruptedException e){}
		  }
		  if(!flag){
		      System.out.println(name + "....." + sex);
		  }
		  flag=true;
		  notify();
	  }
   }
}

class Input implements Runnable{
   int x=0;
   Person p;

   Input(Person p){
      this.p=p;
   }
   public void run(){
       while(true){
				   if(x==1){
					  p.setPerson("hjz", "man");
				   }
				   else p.setPerson("哈哈哈", "女女女女");
				   x=(x+1)%2;
	   }
   }
}

class Output implements Runnable{
   int x=0;
   Person p;
   Output(Person p){
      this.p=p;
   }
   public void run(){
       while(true){
	       p.outPerson();
	   }
   }
}  

public class Test{
    public static void main(String[] args){
	     Person p = new Person();
		 new Thread(new Input(p)).start();
		 new Thread(new Output(p)).start();
	}
}

  

java多线程的等待唤醒机制及如何解决同步过程中的安全问题,布布扣,bubuko.com

时间: 2024-10-05 01:56:45

java多线程的等待唤醒机制及如何解决同步过程中的安全问题的相关文章

java基础知识回顾之java Thread类学习(八)--java多线程通信等待唤醒机制经典应用(生产者消费者)

 *java多线程--等待唤醒机制:经典的体现"生产者和消费者模型 *对于此模型,应该明确以下几点: *1.生产者仅仅在仓库未满的时候生产,仓库满了则停止生产. *2.消费者仅仅在有产品的时候才能消费,仓空则等待. *3.当消费者发现仓储没有产品可消费的时候,会唤醒等待生产者生产. *4.生产者在生产出可以消费的产品的时候,应该通知等待的消费者去消费. 下面先介绍个简单的生产者消费者例子:本例只适用于两个线程,一个线程生产,一个线程负责消费. 生产一个资源,就得消费一个资源. 代码如下: pub

java基础知识回顾之java Thread类学习(七)--java多线程通信等待唤醒机制(wait和notify,notifyAll)

1.wait和notify,notifyAll: wait和notify,notifyAll是Object类方法,因为等待和唤醒必须是同一个锁,不可以对不同锁中的线程进行唤醒,而锁可以是任意对象,所以可以被任意对象调用的方法,定义在Object基类中. wait()方法:对此对象调用wait方法导致本线程放弃对象锁,让线程处于冻结状态,进入等待线程的线程池当中.wait是指已经进入同步锁的线程,让自己暂时让出同步锁,以便使其他正在等待此锁的线程可以进入同步锁并运行,只有其它线程调用notify方

java 22 - 17 多线程之等待唤醒机制(接16)

先来一张图,看看什么叫做等待唤醒机制 接上一章的例子. 例子:学生信息的录入和获取 * 资源类:Student  * 设置学生数据:SetThread(生产者) * 获取学生数据:GetThread(消费者) * 测试类:StudentDemo * 资源类:Student (为了使用等待唤醒机制,添加了个布尔类型的变量,默认为flase) 1 public class Student { 2 String name; 3 int age; 4 boolean flag; // 默认情况是没有数据

多线程的等待唤醒机制之消费者和生产者模式

/** * 等待唤醒之生产者和消费者模型 * 生成者: 创建和添加数据的线程 * 消费者: 销毁和删除数据的线程 * 问题1: 生成者生成数据过快, 消费者消费数据相对慢,不接收数据了, 会造成数据丢失 * 问题2: 消费者消费数据过快, 生成者生成数据相对慢,不发送数据了, 会造成数据被重复读取 * 总结 : 生产数据过快会造成数据丢失 * 生成数据过慢会造成数据被重复读取 * * * wait()和notifyAll()用法: * 1. 必须是同一个对象的wait()和和notifyAll(

多线程等待唤醒机制之生产消费者模式

上篇楼主说明了多线程中死锁产生的原因并抛出问题--死锁的解放方案,那么在本篇文章,楼主将引用一个KFC生产汉堡,顾客购买汉堡的过程来说明死锁解决方案及多线程的等待唤醒机制. 简单地用一幅图来说明KFC生产汉堡,顾客来消费的过程: 场景分析: 资源类:Hamburger 设置汉堡数据:SetThread(生产者) 获取汉堡数据:GetThread(消费者) 测试类:HamburgerTest 不同种类的线程(生产者.消费者)针对同一资源(汉堡)的操作 当汉堡有存货的时候,汉堡师傅不再生产,顾客可消

Android(java)学习笔记71:生产者和消费者之等待唤醒机制

首先我们根据梳理我们之前Android(java)学习笔记70中关于生产者和消费者程序思路: 下面我们就要重点介绍这个等待唤醒机制: 第一步:还是先通过代码体现出等待唤醒机制 package cn.itcast_05; /* * 分析: * 资源类:Student * 设置学生数据:SetThread(生产者) * 获取学生数据:GetThread(消费者) * 测试类:StudentDemo * * 问题1:按照思路写代码,发现数据每次都是:null---0 * 原因:我们在每个线程中都创建了

多线程之Java中的等待唤醒机制

多线程的问题中的经典问题是生产者和消费者的问题,就是如何让线程有序的进行执行,获取CPU执行时间片的过程是随机的,如何能够让线程有序的进行,Java中提供了等待唤醒机制很好的解决了这个问题! 生产者消费者经典的线程中的问题其实是解决线程中的通讯问题,就是不同种类的线程针对同一资源的操作,这里其实有一张图很好的阐述了这其中的问题: 1 //代码中的实体类 2 public class Student { 3 String name; 4 int age; 5 boolean flag; // 默认

java之等待唤醒机制(线程之间的通信)

线程间通信 概念:多个线程在处理同一个资源,但是处理的动作(线程的任务)却不相同.比如:线程A用来生成包子的,线程B用来吃包子的,包子可以理解为同一资源,线程A与线程B处理的动作,一个是生产,一个是消费,那么线程A与线程B之间就存在线程通信问题. 为什么要处理线程间通信: 多个线程并发执行时, 在默认情况下CPU是随机切换线程的,当我们需要多个线程来共同完成一件任务,并且我们希望他们有规律的执行, 那么多线程之间需要一些协调通信,以此来帮我们达到多线程共同操作一份数据. 如何保证线程间通信有效利

Java---18---多线程:等待唤醒机制

class Res { String name; String sex; } class Input implements Runnable { private Res r; public Input(Res r) { // TODO Auto-generated constructor stub this.r = r; } public void run() { int x = 0; while (true) { synchronized (r) { if (x == 0) { r.name