栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Java 中的等待唤醒机制

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java 中的等待唤醒机制

* 生产者消费者模式:
 *         
 *     Student类:     
 *             公共的字段:姓名和年龄(学生数据)
 *  SetThread类:生产者线程
 *          产生学生数据
 *  GetThread类:消费者线程
 *             消费学生数据
 * 
 * 
 *     StudentDemo类:主线程(用户线程): 开启生产者线程和消费者线程!
 * 
 * 问题1:消费者所在的线程和生产者所在的线程操作不是同一个资源对象
 *             null---0
 * 
 * 
 * 
 * 在刚才基础上优化:t1线程:不断产生数据,t2(消费者线程)不断消费数据
 * 在SetThread以及GetThread加入while循环
 * 
 * 
 * 问题2:
 *         1)同一个打印多次
 *         线程在执行的,抢占CPU执行权,如果抢占到CPU的执行权,
 *                 CPU一点点时间片可以让该I线程执行多次
 *         2)发现姓名和年龄不符
 *             线程的执行具有随机性
 * 
 *   针对刚才这个程序,解决线程安全问题:
 *   
 *   检验线程安全问题的标准是什么?
 *    1)是否为多线程环境
 *    2)是否有共享数据
 *    3)是否有多条对共享数据操作
 *    
 *    使用同步机制:synchronized同步代码块解决3)
 *            将多条语句对共享数据的操作包裹起来!
 *    
 *  继续优化:现在想让这个数据依次打印,而不是打印一片数据
 *              "hello",24
 *              "world",39
 *              ..
 *              ..
 *  
 *  引入Java中等待唤醒机制!
 *  
 *  生产者线程:判断是否有数据,没有数据,等待产生数据
 *  消费者线程:判断是否有数据,如果有数据,等待消费掉
 *  
 *  问题:产生死锁!
 *  生产者线程,产生数据了,等待消费数据
 *  消费者线程,消费完数据,等待生产数据
 *  
 *  
 *  
 *  
 *  面试题:
 *          1)sleep()和wait()方法的区别 
 *          
 *  区别1): 来源不同    
 *          sleep()是Thread类中方法
 *          wait()是Object类中方法:需要使用锁对象调用的
 *  
 *      2) 调用方法的时候是否释放锁
 *          sleep(long millis):线程睡眠多少毫秒数据(期间,线程是暂停状态)
 *          wait():线程等待,调用该方法,会立即释放锁对象!利用wait方法会释放锁对象,
 *              然后使用锁对象调用notify(),来完成Java中等待唤醒机制!
 *  
 *      3)共同点:wait和方法sleep()都会可能出现中断异常! InterruptedException
 *          
 *  
 *  
 *      2)wait()和notify()这些方法为什么不定义Thread类中,而是在Object类中呢?

public class StudentDemo {
			
	public static void main(String[] args) {
		
		//同一个学生资源对象
		Student s = new Student() ;
		
		//创建生产者资源类对象以及消费资源类对象
		SetThread st = new SetThread(s) ;
		GetThread gt = new GetThread(s) ;
		
		//创建线程类对象
		Thread t1 = new Thread(st) ;
		Thread t2 = new Thread(gt) ;
		
		t1.start();
		t2.start();
	}
}
//生产者资源类
public class SetThread implements Runnable {
	
	//声明一个学生遍历
	private Student s ;
	public SetThread(Student s) {
		this.s = s ;
	}
	
	//定义一个统计变量
	private int x = 0 ;
	
	@Override
	public void run() {
		//t1线程(生产者线程)
		while(true) {
			if(x % 2== 0) { //x = 0   x =1
				s.name = "hello" ; //设置了 "柯发兴" ,24
				s.age = 24 ;
			}else {
				s.name = "world" ;
				s.age = 39 ; //记录年龄39
			}
			x ++;
			
		}
		
		//产生学生对象,生产数据
//		Student s = new Student() ;
		
	}

}

 

public class Student {
	String name;
	int age;
    boolean flag ;//判断学生存在数据,默认false,不存在;true表示存在数据
}
//消费者资源类
public class GetThread implements Runnable {
	
	//成员变量
	private Student s ;
	public GetThread(Student s) {
		this.s = s ;
	}
	
	@Override
	public void run() {
		
		//不断消费数据
		while(true) {
			
			synchronized(s) {
				//消费者判断如果有数据,先消费掉
				if(!s.flag) {
					try {
						s.wait();//调用wati()会立即释放锁
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
				System.out.println(s.name+"---"+s.age) ;
				
				
				//修饰标记:
				s.flag = false ;//没有数据类
				//通知生产线程产生数据
				s.notify();
			}
			
			
			
			
		}
	
		
	}

}

 

 

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/855149.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号