Java学习_Day18

今天的学习内容
一、线程间通信
二、线程池
三、Lamdba表达式

一、线程间的通信
理解:利用等待(wait)和唤醒(notify)机制,让多个线程之间达到协同合作的目的
注意:等待(wait)唤醒(notify) 都必须被锁对象调用
等待和唤醒案例(生产者和消费者)
包子类(共享资源)`

public class BaoZi{
	//皮
	String pi;
	//馅
	String xian;
	//状态  有(true)   没有(false)
	boolean flag;
} 

生产者线程(包子铺)

public class BaoziPu extends Thread{
	//共享资源(作为锁对象)
	private BaoZi bz;
	//创建对象的时候给bz对象赋值
	public BaoziPu(BaoZi bz){
		this.bz=bz;
	}
	
	@Override
	public void run(){
		int count=0; //计数器
		while(true){
			//先对包子的状态进行判断,有(等待),没有(做包子)
			synchronized(bz){
				//有包子(等待)
				if(bz.flag){
					try{
						bz.wait();
					}catch(Exception e){
						e.printStackTrace();
					}
				}
				//等待完了没有包子(做包子)
				try{
					//做包子得花费1秒钟的时间
					Thread.sleep(1000);
				}catch(Exception e){
					e.printStackTrace();
				}
				//表示做"薄皮"+"三鲜馅"的包子
				if(count%2==0){
					bz.pi="薄皮";
					bz.xian="三鲜馅"
					
				}else if(count%2==1){
					//表示做"冰皮"+"牛肉馅"的包子
					bz.pi="冰皮";
					bz.xian="牛肉馅";
				}
				count++;
				//包子做好了,改变包子的状态为有包子
				bz.flag=true;
				System.out.println(bz.pi+bz.xian+"包子做好了,吃货可以吃包子了...");
				bz.nofiy(); //唤醒顾客吃包子
			}
		}
	}
} 

消费者线程(顾客)

public class Customer extends Thread{
	private BaoZi bz;
	
	public Customer(BaoZi bz){
		this.bz=bz;
	}
	
	@Override
	public void run(){
		while(true){
			synchronized(bz){
				//如果没有包子等待,有包子吃包子
				if(!bz.flag){
					try{
						bz.wait();
					}catch(Exception e){
						e.printStackTrace();
					}
				}
				//包子做好了,就可以吃包子了
				System.out.println("顾客开始吃"+bz.pi+bz.xian+"的包子");
				bz.flag=false; //吃完包子,包子的状态给为false
				bz.notify(); //唤醒包子铺做包子
			}
		}
	}
}

测试类

public class Demo{
	public static void main(String[] args){
		BaoZi bz=new BaoZi();
		//创建包子铺线程对象,传递共享资源  “包子对象”
		BaoziPu bzp=new BaoziPu(bz);
		bzp.start();
		
		//创建顾客线程对象,传递共享资源  “包子对象”
		Customer cs=new Customer(bz);
		cs.start();
	}
}

二、线程池
JDK1.5之后就提供了线程池,方便执行线程任务
在这里插入图片描述

//第一步:获取线程池对象
	ExecutorService service=Executors.newFixedThreadPool(2); //包含2个线程的线程池

	//第二步:提交线程任务
	service.submit(new Runnable(){
		@Override
		public void run(){
			System.out.println(Thread.currentThread().getName()+"线程任务执行了");
		}
	});
	
	service.submit(new Runnable(){
		@Override
		public void run(){
			System.out.println(Thread.currentThread().getName()+"线程任务执行了");
		}
	}); 
	
	
	//第三步:销毁线程池(不建议),线程池就没有用了。
	service.shutdown();

三、Lamdba表达式
函数式接口:
只能有一个抽象方法的接口,但是可以有其他方法。
@FunctionalInterface 标记接口为函数式接口

使用Lamdba表达式的前提
1)必须要有一个函数式接口
2)Lambda表达式可以理解为函数式接口的实例实现(可以有效优化匿名内部类代码的冗余)

Lamdba表达式的格式
//标准格式
(Type1 param1,Type2 param2)->{… return 返回值;}
//省略数据类型
(param1,param2)->{… return 返回值;}
//省略{}以及return语句。 【如果语句体只有一条语句】
(param1,param2)-> 语句体;
//省略() 【如果参数只有一个,才能省略()】
param1-> 语句体;

Lamdba表达式的使用步骤

1)需要先有一个函数式接口
2)写一个方法,把函数式接口作为方法的参数
3)调用方法,传递的实际参数对函数式接口进行实现

函数式接口实现方式一:使用匿名内部类(代码冗余)
函数式接口实现方式二:使用Lamdba表达式(减少代码冗余)

//1)需要先有一个函数式接口
@FunctionalInterface
public interface Cook{
	public abstract void makeFood(); //做食物
}

//写一个测试类
public class Demo1{
	public static void main(String[] args){
		//3)调用方法,匿名内部类对函数式接口进行实现
		invokeCook(
			new Cook(){
				public void makeFood(){
					System.out.println("烹饪大米饭");
				}
			}
		);
		
		//3)调用方法,Lamdb表达式对函数式接口进行实现
		invokeCook(
			()->{
				System.out.println("烹饪小米粥");
			}
		); 
	}
	//2)写一个方法,把函数式接口作为方法的参数
	public static void invokeCook(Cook cook){
		cook.makeFood();
	}
}

lambda表达式就是简化匿名内部类的写法
上面时候用到匿名内部类并要复写里面的方法,就可以考虑使用lambda表达式来简化

Java学习第19天内容链接:
https://blog.csdn.net/LJN951118/article/details/89409936

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值