4

狂神说 多线程_wx60ade3d788c21的技术博客_51CTO博客

 1 year ago
source link: https://blog.51cto.com/u_15227402/5931149
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

狂神说 多线程

精选 原创

红烧瓜皮 2022-12-12 16:43:55 博主文章分类:狂神说 ©著作权

文章标签 代码块 线程安全 线程同步 文章分类 Java 编程语言 yyds干货盘点 阅读数151

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();
狂神说 多线程_线程同步_02
狂神说 多线程_线程同步_03
线程休眠sleep Thread.sleep

100ms==1s

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

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

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

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

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

可以想象成插队

观测线程状态
  • 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线程协作

生产者消费者模式 问题

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

狂神说 多线程_代码块_04
狂神说 多线程_线程同步_05
狂神说 多线程_代码块_06

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK