多线程
线程创建
继承Thread类
- 自定义线程类 extends Thread
- 重写run()方法,编写线程执行体
- 创建线程对象,调用start()方法启动线程:
子类对象.start()
- 线程不一定立即执行,由CPU安排调度
- 缺点:OOP单继承局限性
实现Runnable接口
- 自定义Runnable类 implements Runnable
- 重写run()方法,编写线程执行体
- 创建线程对象,调用start()方法启动线程:
传入目标对象+Thread对象.start()
- 推荐使用Runnable对象,方便同一个对象被多个线程使用。一份资源,多个代理
实现Callable接口
- 实现Callable接口,需要返回值类型 implements Callable
- 重写call()方法,需要在main()函数抛出异常
- 创建目标对象
- 创建执行服务
ExecutorService ser = Executors.newFixedThreadPool(3);
- 提交执行
Future<Boolean> r1 = ser.submit(t1);
- 获取结果
boolean rs1 = r1.get();
- 关闭服务
ser.shutdownNow();
- Callable接口不常用,了解即可
- 优点:1.可以定义返回值; 2.可以抛出异常
函数式接口
任何接口,如果只包含唯一一个抽象方法,那么它就是函数式接口
1
2
3public interface Runnable {
public abstract void run();
}对于函数式接口,可以通过lambda表达式来创建该接口的对象
用lambda表达式的好处: 1.避免匿名内部类定义过多;2.简洁代码
注解
三个内置注解
@Override
@Deprecated
@SuppressWarnings("all")
四个元注解
Target(value = {ElementType.METHOD, ElementType.TYPE})
Target表示我们的注解可以用在哪些地方@Retention(value = RetentionPolicy.RUNTIME)
Retention表示我们的注解在什么地方有效(runtime>class>sources 一般都用runtime)@Documented
Documented表示是否将我们的注解生成在JAVAdoc中@Inherited
Inherited表示子类可以继承父类的注解
四个元注解,重点是Target和Retention,基本是必写
自定义注解
- 用@interface自定义注解
1
2
3
4
5
6
MyAnnotation {
//如果只有一个参数,建议用value命名
String value();
} - 注解的参数:参数类型 参数名();
1
2
3
4String value() default "";
int age() default 0;
int id() default -1; //-1代表不存在
String[] schools() default {"monash", "utas"};