狂神说 多线程

时间:2022-12-12 18:05:45

多线程

start() 和 run() 的区别?

狂神说 多线程

线程不一定执行 由cpu调度安排

继承Thread类
  • 子类继承Thread类具备多线程能力
  • 启动线程:子类对像.start()
  • 不建议使用:避免oop单继承局限性
new THread(new MyThread()).start();
实现Runnable接口
  • 具有多线程能力
  • 启动线程: 传入目标对象+Thread对象.start()
  • 推荐使用:避免单继承局限性,方便同一个对象被多个线程使用· ·3AQ`
实现Callable接口
1.实现Callable接口,需要返回值类型
2.重写call方法,需要抛出异常
3.创建目标对象
4.创建执行服务: ExecutorService ser = Executors.newFixedThreadPool(1);
5.提交执行: Future<Boolean> result1 = ser. submit(t1);
6.获取结果: boolean r1 = result1.get()
7.关闭服务: ser.shutdownNow();
静态代理
lambda表达式
  • 避免匿名内部类定义过多
  • 看起来更简洁
  • 去掉了一些无意义的代码
函数式接口(Functional interface)的定义:
  • 任何接口,入伙只包含唯一一个抽象的方法,那么就是一个函数式接口
public interface Runnable(){
punlic abstract void run();
}
  • 对于函数式接口,我们可以通过lambda表达式来创建接口的对象
new Thread(()->sout("hhhhhhh")).start();
线程状态

狂神说 多线程


线程方法

狂神说 多线程

线程休眠sleep Thread.sleep

100ms==1s

  • sleep (时间)指定当前线程阻塞的毫秒数;
  • sleep存在异常 InterruptedException;
  • sleep时间达到后线程进入就绪状态;
  • sleep可以模拟网络延时,倒计时等
  • 每一个对象都有一个锁,
  • sleep不会释放锁;
线程礼让yield Thread.yield()

让当前正在执行的线程暂停,但不阻塞

让线程从运行状态转为就绪状态

让cpu重新调度,礼让不一定成功! 看cpu心情

join

join合并线程,代词线程执行完成后 在执行其他线程,其他线程阻塞

可以想象成插队

观测线程状态
  • NEW
  • RUNNABLE
  • TIME_WAITTING
  • TERMINATED
线程优先级

用数字表示 范围从1~10.

Thread.MIN_PRIORITY=1;
Thread.MAX_PRIORITY=10;
Thread.NORM_PRIORITY=5;

//改变或者获取优先级
getPriority().setPriority(int xxx)
守护(daemon)线程

线程分为:用户线程 和 守护线程

虚拟机必须确保用户线程执行完毕

虚拟机不用等待守护线程执行完毕

线程同步机制

线程同步其实就是一个等待机制

默认的ArryList 线程不安全
CopyOnWriteArryLIst 线程安全
队列和锁

锁机制

synchronized 默认锁的是run

synchronized(锁的对象){
//代码块
}
//锁的对象:需要增删改的对象
死锁

都在等待对方的资源

解决方法:不要抱对方的锁 ,从代码块中拿出来

产生死锁的四个必要条件:

1.互斥条件:一个资源每次只能被一一个进程使用。 2.请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。 3.不剥夺条件:进程已获得的资源,在末使用完之前,不能强行剥夺。 4.循环等待条件:若干进程之间形成- -种头尾相接的循环等待资源关系。

Lock(锁)
class A{
private finall ReenTrantLock lock = new ReenTrantLock();
public void m(){
lock.lock();
try{
//保证线程安全的代码

}finally{
lock.unlock();
//如果同步代码有异常,要将unlock()写入finally语句块
}
}
}

◆从JDK 5.0开始,Java提供了更强大的线程同步机制一通过 显式定义同步锁对 象来实现同步。同步锁使用Lock对象充当 ◆java.util.concurrent.locks.Lock接口是控制多个线程对共享 资源进行访问的工具。 锁提供了对共享资源的独占访问,每次只能有一-个线程对Lock对象加锁,线程开 始访问共享资源之前应先获得L ock对象 ◆ReentrantLock(可重入锁)类实现了Lock,它拥有与synchronized相同的并发性和内存语 义,在实现线程安全的控制中,比较常用的是ReentrantLock,可以显式加锁、释 放锁。

synchronized与Lock的对比

◆Lock是显式锁(手动开启和关闭锁,别忘记关闭锁) synchronized是隐式锁,出了 作用域自动释放 ◆Lock只有代码块锁,synchronized有 代码块锁和方法锁 ◆使用Lock锁,JVM将花费较少的时间来调度线程,性能更好。并且具有更好的扩展 性(提供更多的子类) ◆优先使用顺序: ◆Lock >同步代码块(已经进入了方法体,分配了相应资源) >同步方法(在方法体之外)

04线程协作

生产者消费者模式 问题

线程通信

应用场景:生产者和消费者问题 ◆假设仓库中只能存放一件产品,生产者将生产出来的产品放入仓库,消费者将 仓库中产品取走消费 ◆如果仓库中没有产品,则生产者将产品放入仓库,否则停止生产并等待,直到 仓库中的产品被消费者取走为止. ◆如果仓库中放有产品,则消费者可以将产品取走消费,否则停止消费并等待, 直到仓库中再次放入产品为止.

狂神说 多线程

狂神说 多线程

狂神说 多线程

管程法
信号灯法
线程池