黑马程序员-JAVA基础-多线程间的通信、等待唤醒机制和新特性

------- android培训java培训、期待与您交流! ---------

多线程(三)

多线程间的通信:不同功能的代码封装在不同的线程代码中操作共同的资源。

实现的思想:

        1.两线程实现Runnable接口,必须传入同一个对象

        2.建立一资源类,设置成员变量,就是线程中的共享数据

        3.在实现Runnable的子类中,将资源类名设置为成员变量,设置构造函数传入的参数为资源类型的变量,复写run()方法,操作资源数据。

等待唤醒机制:Wait()——notify(),判断条件为if

        当线程中的通信操作同一功能的线程出现两个以上时,出现资源中的数据不匹配的情况,因此用等待唤醒机制,将资源数据中的输出统一。既输入线程中设置一组变量后就等待,并唤醒输出线程,输出数据完成后,将其等待并唤醒输入线程,这样设置会让数据匹配。但出现另外一种情况,就是某一时间段输入一组数据,但却输出两组数据。因为线程运行时,内存中会建立线程池,等待线程会存在线程池中,当唤醒时唤醒的是线程池中的线程,且Wait()notify()需要标识锁,通常唤醒第一个被等待的,这样就会出现了的一种情况,t1t2为输入线程,当t1线程等待后,t2线程先抢到CPU执行权,但因为标识为truet2也等待;t3t4为输出线程,当t3输出后,先唤醒t1,判断标识t3等待后,t1完成了输入,因为t2先等待,所以t2先被唤醒,导致输入两次,t2等待后,t3被唤醒输出一次,这样就导致了输入了两次,但只输出了一次。

private boolean flag = false;
			//  t1    t2
	public synchronized void set(String name)
	{
		while(flag)
			try{this.wait();}catch(Exception e){}//t1(放弃资格)  t2(获取资格)
		this.name = name+"--"+count++;

		System.out.println(Thread.currentThread().getName()+"...生产者.."+this.name);
		flag = true;
		this.notifyAll();
	}
	//  t3   t4  
	public synchronized void out()
	{
		while(!flag)
			try{wait();}catch(Exception e){}//t3(放弃资格) t4(放弃资格)
		System.out.println(Thread.currentThread().getName()+"...消费者........."+this.name);
		flag = false;
		this.notifyAll();
	}
}

解决方式一:

        Wari()——notifyall(),判断条件为while

判断条件为while后,每次都要判断后才能wait,notifyall可以将等待的输出线程全部唤醒。

解决方式二:1.5新特性Lokunlock

         Lock接口,ReentrantLockLock的实现类,有一些方法void | lock()获取锁,void | unlock释放锁;Condition | newCondition返回实例对象,该类中还有有void | await()等待方法,void | signal唤醒一个等待线程,这样可以用(对象. Signal)来唤醒指定线程。

private Condition condition_pro = lock.newCondition();
	private Condition condition_con = lock.newCondition();



	public  void set(String name)throws InterruptedException
	{
		lock.lock();
		try
		{
			while(flag)
				condition_pro.await();//t1,t2
			this.name = name+"--"+count++;

			System.out.println(Thread.currentThread().getName()+"...生产者.."+this.name);
			flag = true;
			condition_con.signal();
		}
		finally
		{
			lock.unlock();//释放锁的动作一定要执行。
		}
	}

        多线程中还有关于并发库也就是 Executors、ExecutorService线程池、调度器 ScheduledExecutorService的应用,后续在交通灯管理项目中会提到,这里就不赘述了。

    总结:关于JAVA基础中的线程,当初学习毕老师的视频时个人觉得最难的还是生产消费模型和死锁,写这部分又不想把老师的所有的代码都写出来,太占篇幅,所以截取了部分代码,学习多线程个人觉得这些机制(同步、死锁、多线程间的通信等等)出现的原因弄清楚,多线程大概也就好理解了。再就是面对对象的理解,资源类怎么和线程类联系起来,各类之间的数据怎么联系起来,这几篇当中我根据自己的理解也介绍了下,个人觉得这对于我们这些初学者来说才是最关键的,便于我们理解代码和自己写代码。


------- android培训java培训、期待与您交流! ---------

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值