Java线程

本文详细介绍了Java中创建和运行线程的三种方法,包括直接使用Thread类、实现Runnable接口以及结合FutureTask。同时,文章深入探讨了Thread与Runnable的关系,并通过实例展示了Java 8以后使用Lambda表达式简化代码的过程。此外,还讲解了Lambda表达式的语法、常用示例以及引用已存在方法的用法,强调了其在简化代码和提高代码可读性方面的作用。
摘要由CSDN通过智能技术生成

Java线程

创建和运行线程

方法一:直接使用Thread

//创建线程对象
Thread t = new Thread(){
    public void run(){
        //要执行的任务
    }
};
//启动线程
t.start();

例如:

//构造方法的参数是给线程指定名字,推荐
Thread t1 = new Thread("t1"){
    @override
    public void run(){
        //执行的代码
    }
};
//t1.setName("t1");//这种方式也可以给线程命名
t1.start();

方法二:实现Runnable接口,使用Runnable配合Thread

把【线程】和【任务】分开

  • Thread代表线程
  • Runnable代表可运行的任务(线程要执行的代码)
Runnable runnable = new Runnable(){
    public void run(){
        //要执行的代码
    }
};
//创建线程对象
Thread t = new Thread(runnable);
//启动线程
t.start();

例如:

//创建任务对象
Runnable task2 = new Runnable(){
    @Override
    public void run(){
        //要执行的代码
    }
};
//创建线程对象(参数1 是任务对象;参数2 是线程名字,推荐)
Thread t = new Thread(task2,"t");
//启动线程
t.start();

Java8以后,可以使用lambda精简代码

//创建任务对象
Runnable task2 = () -> {log.debug("hello");};

//参数1 是任务对象;参数2 是线程名字, 推荐
Thread t2 = new Thread(task2, "t2");
//启动线程
t2.start();

方法三:FutureTask与Thread结合

FutureTask能够接收Callable类型的参数,用来处理有返回结果的情况

//创建任务对象
FutureTask<Integer> task3 = new FutureTask<>(() -> {
    log.debug("hello");
    return 100;
});

//参数1 是任务对象;参数2 是线程名字  推荐
new Thread(task3,"t3").start();

//主线程阻塞,同步等待task执行完毕的结果
Integer result = task3.get();
log.debug("结果是:{}",result);

原理之Thread与Runnable的关系

分析Thread源码,理清它与Runnable的关系(去看源码,两者都是调用了Thread中的run方法)

小结

  • 用Runnable将线程跟任务拆分开了,更方便使用
  • 用Runnable更容易与线程池等高级api配合
  • 用Runnable让任务类脱离了Thread继承体系,更灵活

lambda表达式

对接口的要求

  • 虽然使用lambda表达式可以对某些接口进行简单的实现,但并不是所有的接口都可以使用lambda表达式来实现。lambda规定接口中只能有一个被实现的方法,不是规定接口中只能有一个方法
  • jdk8中有另外一个新特性:default,被default修饰的方法会有默认实现,不是必须被实现的方法,所以不影响lambda表达式的使用。

@FunctionalInteface

修饰函数式接口的,要求接口中的抽象方法只有一个。这个注解往往会和lambda表达式一个出现。有这个注解代表可以使用lambda表达式。

lambda的基础语法

这里给出了六个接口,后文的全部操作都利用这六个接口来进行阐述。

/**多参数无返回*/
@FunctionalInterface
public interface NoReturnMultiParam {
    void method(int a, int b);
}

/**无参无返回值*/
@FunctionalInterface
public interface NoReturnNoParam {
    void method();
}

/**一个参数无返回*/
@FunctionalInterface
public interface NoReturnOneParam {
    void method(int a);
}

/**多个参数有返回值*/
@FunctionalInterface
public interface ReturnMultiParam {
    int method(int a, int b);
}

/*** 无参有返回*/
@FunctionalInterface
public interface ReturnNoParam {
    int method();
}

/**一个参数有返回值*/
@FunctionalInterface
public interface ReturnOneParam {
    int method(int a);
}

语法形式为 () -> {},其中 () 用来描述参数列表,{} 用来描述方法体,-> 为 lambda运算符 ,读作(goes to)。

import lambda.interfaces.*;

public class Test1 {
    public static void main(String[] args) {

        //无参无返回
        NoReturnNoParam noReturnNoParam = () -> {
            System.out.println("NoReturnNoParam");
        };
        noReturnNoParam.method();

        //一个参数无返回
        NoReturnOneParam noReturnOneParam = (int a) -> {
            System.out.println("NoReturnOneParam param:" + a);
        };
        noReturnOneParam.method(6);

        //多个参数无返回
        NoReturnMultiParam noReturnMultiParam = (int a, int b) -> {
            System.out.println("NoReturnMultiParam param:" + "{" + a +"," + + b +"}");
        };
        noReturnMultiParam.method(6, 8);

        //无参有返回值
        ReturnNoParam returnNoParam = () -> {
            System.out.print("ReturnNoParam");
            return 1;
        };

        int res = returnNoParam.method();
        System.out.println("return:" + res);

        //一个参数有返回值
        ReturnOneParam returnOneParam = (int a) -> {
            System.out.println("ReturnOneParam param:" + a);
            return 1;
        };

        int res2 = returnOneParam.method(6);
        System.out.println("return:" + res2);

        //多个参数有返回值
        ReturnMultiParam returnMultiParam = (int a, int b) -> {
            System.out.println("ReturnMultiParam param:" + "{" + a + "," + b +"}");
            return 1;
        };

        int res3 = returnMultiParam.method(6, 8);
        System.out.println("return:" + res3);
    }
}

Lambda 语法简化

我们可以通过观察以下代码来完成代码的进一步简化,写出更加优雅的代码。

import lambda.interfaces.*;

public class Test2 {
    public static void main(String[] args) {

        //1.简化参数类型,可以不写参数类型,但是必须所有参数都不写
        NoReturnMultiParam lamdba1 = (a, b) -> {
            System.out.println("简化参数类型");
        };
        lamdba1.method(1, 2);

        //2.简化参数小括号,如果只有一个参数则可以省略参数小括号
        NoReturnOneParam lambda2 = a -> {
            System.out.println("简化参数小括号");
        };
        lambda2.method(1);

        //3.简化方法体大括号,如果方法条只有一条语句,则可以s省略方法体大括号
        NoReturnNoParam lambda3 = () -> System.out.println("简化方法体大括号");
        lambda3.method();

        //4.如果方法体只有一条语句,并且是 return 语句,则可以省略方法体大括号
        ReturnOneParam lambda4 = a -> a+3;
        System.out.println(lambda4.method(5));

        ReturnMultiParam lambda5 = (a, b) -> a+b;
        System.out.println(lambda5.method(1, 1));
    }
}

Lambda 表达式常用示例

lambda表达式引用方法

有时候我们不是必须要自己重写某个匿名内部类的方法,我们可以可以利用 lambda表达式的接口快速指向一个已经被实现的方法。

语法

方法归属者::方法名 静态方法的归属者为类名,普通方法归属者为对象

public class Exe1 {
    public static void main(String[] args) {
        ReturnOneParam lambda1 = a -> doubleNum(a);
        System.out.println(lambda1.method(3));

        //lambda2 引用了已经实现的 doubleNum 方法
        ReturnOneParam lambda2 = Exe1::doubleNum;
        System.out.println(lambda2.method(3));

        Exe1 exe = new Exe1();

        //lambda4 引用了已经实现的 addTwo 方法
        ReturnOneParam lambda4 = exe::addTwo;
        System.out.println(lambda4.method(2));
    }

    /**
     * 要求
     * 1.参数数量和类型要与接口中定义的一致
     * 2.返回值类型要与接口中定义的一致
     */
    public static int doubleNum(int a) {
        return a * 2;
    }

    public int addTwo(int a) {
        return a + 2;
    }
}
构造方法的引用

一般我们需要声明接口,该接口作为对象的生成器,通过 类名::new 的方式来实例化对象,然后调用方法返回对象

interface ItemCreatorBlankConstruct {
    Item getItem();
}
interface ItemCreatorParamContruct {
    Item getItem(int id, String name, double price);
}

public class Exe2 {
    public static void main(String[] args) {
        ItemCreatorBlankConstruct creator = () -> new Item();
        Item item = creator.getItem();

        ItemCreatorBlankConstruct creator2 = Item::new;
        Item item2 = creator2.getItem();

        ItemCreatorParamContruct creator3 = Item::new;
        Item item3 = creator3.getItem(112, "鼠标", 135.99);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值