Java多线程(lambda表达式)
目录
- Java多线程(lambda表达式)
- 线程创建
- 继承Thread类
- 实现Rannable接口
- 实现Callable接口
- 优点
- 静态代理模式
- Lambda表达式
- 线程状态
- 状态观测
- 线程方法
- 线程停止
- 线程休眠sleep
- 线程礼让yield
- 线程阻塞join
- 线程优先级setPriority
- 守护线程setDaemon
- 线程同步
- 同步块
- 死锁
- 死锁产生的四个条件
- Lock锁
- 线程通信
- 线程池
线程创建
继承Thread类
- 自定义线程类继承Thread类
- 重写run()方法,编写线程执行体
- 创建线程对象,调用start()方法启动线程
实现Rannable接口
由于java单继承的局限性,推荐使用此方法
- 定义MyRunnable类实现Runnable接口
- 实现run()方法,编写线程执行体
- 创建线程对象,通过线程对象调用start方法(静态代理)
new Thread(MyRunnable).start();
实现Callable接口
- 实现Callable接口,需要返回值类型
- 重写call方法,需要抛出异常
- 创建目标对象
- 创建执行服务:
ExecutorService ser = Executors.newFixedTreadPool(nThreads);
- 提交执行:
Future<Boolean> result = ser.submit(MyCallable);
- 获取结果
boolean r = result.get();
- 关闭服务
ser.shutdownNow();
优点
- 可以提供返回值
- 可以抛出异常
静态代理模式
- 真实对象和代理对象实现同一个接口
- 代理对象要代理真实对象
好处:
- 代理对象可以做很多真实对象做不了的事情
- 真实对象专注做自己的事情
new Thread(() -> {...}).start();
Lambda表达式
- 函数式编程
- 函数式接口
- 只包含唯一一个抽象方法的接口
- 使用lambda表达式来创建函数式接口的对象
- (参数) -> 表达式\语句\代码块
- 多个语句用{}
- 参数可以去掉类型,要去掉都去掉
- 单个参数可以省略括号
线程状态
- 创建状态
- 就绪状态
- 阻塞状态
- 运行状态
- 死亡状态
状态观测
- Thead.State state = thread.getState()
- NEW:创建状态
- RUNNABLE:运行状态
- BLOCKED:阻塞,等待监视器锁定
- WAITTING:阻塞,等待另一个线程执行动作
- TIMEED_WAITTING:阻塞,等待另一个线程执行动作达到指定时间
- TERMINATED
线程方法
线程停止
- 建议使用flag让线程自己停下来
private boolean flag = true;
@Override
public void run(){
while(flag){
...
}
}
public void stop(){
this.flag = false;
}
线程休眠sleep
- 指定线程阻塞的毫秒数
- 存在异常InterruptedException
- 时间到后线程进入就绪状态
- 不会释放线程锁
线程礼让yield
- 让当前正在执行的线程暂停,但不阻塞
- 将线程从运行状态转为就绪状态
- 礼让不一定成功
线程阻塞join
- 等待该线程执行完后,再执行其他线程
- 当前线程阻塞
线程优先级setPriority
- 范围1~10
- Tread.MIN_PRIORITY = 1;
- Tread.Max_PRIORITY = 1;
- Tread.NORM_PRIORITY = 5;
守护线程setDaemon
- 线程分为用户线程和守护线程
- 虚拟机必须确保用户线程执行完毕
- 虚拟机不用等待守护线程执行完毕
- 如:后台记录操作日志、监控内存、垃圾回收等
线程同步
- 并发:多个线程同时操作同一个对象
- 同时访问时,进入对象的等待池
- 锁机制:synchronized方法和synchronized块
同步块
- synchronized(Obj)
- Obj称为同步监视器
- 同步监视器可以是任何对象,推荐使用共享资源作为同步监视器
- 同步方法中的同步监视器就是this
- Obj得是同一个实例,才能锁住
死锁
- 多个线程互相等待对方释放资源
- 某一个同步块同时拥有两个以上对象的锁时,就可能会发生死锁
死锁产生的四个条件
- 互斥条件:一个资源每次只能被一个进程使用
- 请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放
- 不剥夺条件:进程已获得的资源,在未使用完之前,不能强行剥夺
- 循环等待的条件:若干进程之间形成一种头尾相接的循环等待资源关系
Lock锁
- JDK5.0开始,通过显式定义同步锁对象来实现同步
- 常用Lock接口的实现类ReentrantLock(可重入锁)
private final ReentrantLock lock = new ReentrantLock();
lock.lock();
lock.unlock();
线程通信
在同步方法或同步代码块中使用:
- wait():一直等待,会释放锁
- wait(long timeout):等待指定毫秒数
- notify():唤醒一个处于等待状态的线程
- notifyAll():唤醒同一个对象上所有等待的线程
线程池
- 提前创建好多个线程,放入线程池中,使用时直接获取,使用完放回池中。
- ExecutorService:线程池接口,常见子类ThreadPoolExecutor
- void execute(Runnable command)
- task):
- void shutdown()
- Executors:工具类、线程池的工厂类,用于创建并返回不同类型的线程池