①.实现Callable接口-了解
- 实现Callable接口
- 重写call方法,需要抛出异常
- 创建目标对象
- 执行服务:ExecutorService ser = Executors.newFixedThreadPool(1);
- 提交执行:Future result1 = ser.submit(t1);
- 获取结果:boolean r1 = result.get();
- 关闭服务:ser.shutdownNow();
使用实现Callable方法下载网络图片
//多线程创建方式三,实现Callable接口
public class TestCallable implements Callable<Boolean>{
private String url; //网络图片地址
private String name; //保存的文件名
public TestCallable(String url,String name){
this.url = url;
this.name = name;
}
//重写call方法
@Override
public Boolean call() {
WedDownLoader wedDownLoader = new WedDownLoader();
wedDownLoader.downLoader(url,name);
System.out.println("下载了文件名为" + name + "的文件");
return true;
}
public static void main(String[] args) throws ExecutionException, InterruptedException {
TestCallable c1 = new TestCallable("图片网址1","C1.jpg");
TestCallable c2 = new TestCallable("图片网址2","C2.jpg");
TestCallable c3 = new TestCallable("图片网址3","C3.jpg");
//创建执行服务
ExecutorService ser = Executors.newFixedThreadPool(3); //创建的线程数
// 提交执行刚才新建的线程
Future<Boolean> r1 = ser.submit(c1);
Future<Boolean> r2 = ser.submit(c2);
Future<Boolean> r3 = ser.submit(c3);
//获取返回值结果:
boolean rs1 = r1.get();
boolean rs2 = r2.get();
boolean rs3 = r3.get();
//关闭服务:
ser.shutdownNow();
}
}
/*
Callable可以定义返回值,可以抛出异常
*/
//下载器
class WedDownLoader2{
//下载方法
public void downLoader(String url,String name){
try {
FileUtils.copyURLToFile(new URL(url),new File(name));
} catch (IOException e) {
e.printStackTrace();
System.out.println("IO异常:downloader方法出现问题");
}
}
}
②.静态代理
实现静态代理对比Tread
例子:
结婚人:真实角色
婚庆公司:代理结婚人处理结婚事物
结婚:实现结婚接口
/*
静态代理模式总结:
1.真是对象和代理对象都要实现同一个接口
2.代理对象需要代理真实角色
好处:
1.代理对象可以实现很多真实对象实现不了的功能
2.真实对象可以专注做自己的事情
*/
public class StaticProxy {
public static void main(String[] args) {
//线程通过Thread方法来实现Runnable接口的功能
new Thread(()-> System.out.println("我爱你")).start();
//静态代理通过 代理方法 实现 实例对象额 功能 是多线程实现的本质原理
new WeddingCompany(new You()).HappyMarry(); //下面两行代码的精简
/*
原本实现结婚功能
You you = new You();
you.HappyMarry();
*/
//静态代理之后,将实例对象You传给代理对象
WeddingCompany weddingCompany = new WeddingCompany(new You());
//由代理对象去执行You本来要做的事情,并且做到更多事情的扩展
weddingCompany.HappyMarry();
}
}
interface Marry{
//
void HappyMarry();
}
//You是一个真是角色,You去结婚
class You implements Marry{
@Override
public void HappyMarry() {
System.out.println("你要结婚了,心情很不错");
}
}
//WeddingCompany是代理角色,帮助You实现结婚的各种事物
class WeddingCompany implements Marry{
//创建结婚的目标对象 真实的目标角色
private Marry target;
//构造方法
public WeddingCompany (Marry target){
this.target = target;
}
@Override
public void HappyMarry() {
before();
this.target.HappyMarry(); //这就是真实对象
after();
}
private void after() {
System.out.println("结婚后,收婚庆代理尾款");
}
private void before() {
System.out.println("结婚前,布置婚房,布置现场");
}
}
③.Lambda表达式
- 希腊字母的第十一个字母 λ 英语名称为Lambda
- 出现的作用:减少匿名内部类的定义过多
- 其实是属于函数式编程的概念
(params) -> expression [表达式]
(params) -> statement [语句]
(params) -> { statements }- new Tread( () -> System.out.println(“多线程学习…”) ).start();
- 为什么会出现Lambda表达式
避免匿名内部类定义过多
可以让代码看起来更加的简洁
去掉了一堆没有意义的代码,只留下了核心的逻辑
理解Function Interface (函数式接口) 是学习Java 8 Lambda表达式的关键
- 函数式接口的定义
任何接口,如果只包含了一个抽象方法,那么它就是一个函数式接口
对于函数式接口,我们便可以通过Lambda表达式来创建对象逐步简化代码的思路
public class TestLambda {
//3.静态内部类
static class Like2 implements ILike{
@Override
public void lambda() {
System.out.println("I like lambda2!");
}
}
public static void main(String[] args) {
ILike like = new Like();
like.lambda(); //输出:I like lambda1!
like = new Like2();
like.lambda(); //输出:I like lambda2!
//4.局部内部类
class Like3 implements ILike{
@Override
public void lambda() {
System.out.println("I like lambda3!");
}
}
like = new Like3();
like.lambda(); //输出:I like lambda3!
//5.匿名内部类,没有类的名称,必须借助接口或者父类
like = new ILike() {
@Override
public void lambda() {
System.out.println("I like lambda4!");
}
};
like.lambda(); //输出:I like lambda4!
//6.使用Lambda简化,只用关注函数的核心实现就可以了
like = () ->{
System.out.println("I like Lambda5!");
};
like.lambda(); //输出:I like lambda5!
}
}
//1.定义一个函数式接口
interface ILike{
void lambda();
}
//2.实现类,实现接口的方法
class Like implements ILike{
@Override
public void lambda() {
System.out.println("I like lambda1!");
}
}
Lambda表达式语法的简化
public class TestLambda2 {
public static void main(String[] args) {
ILove love = null;
//1.简化lambda表达式
love = (String who) -> {
System.out.println("I love " + who);
};
//2.简化参数类型
love = (who) -> {
System.out.println("I love " + who);
};
//3.简化括号,仅限于只有一个参数时可以简化括号
love = who -> {
System.out.println("I love " + who);
};
//4.简化花括号,仅限于实现类当中仅有一条语句的情况
love = who -> System.out.println("I love " + who);
love.Love("iFinder001");
}
}
//定义一个函数式接口ILove,定义该接口的实现方法
interface ILove{
void Love(String who);
}
总结:
1.只有函数式接口可以使用Lambda表达式
2.多个参数,也可以去掉参数类型,但是不能去掉括号 (who1,who2)
3.多线程当中,Runnable接口就是一个函数式接口,当需要用某个类实现Runnable接口并且代码不复杂的就可以利用Lambda表达式。