Java中的多线程

多线程

概述

​ 程序是指令和数据的有序集合,其本身没有任何运行的含义,是一个静态的概念。
​ 而进程则是执行程序的一次执行过程,它是一个动态的概念。是系统资源分配的单位通常在一个进程中可以包含若干个线程,当然一个进程中至少有一个线程,不然没有存在的意义。线程是CPU调度和执行的的单位。

​ 很多多线程是模拟出来的,真正的多线程是指有多个cpu,即多核,如服务器。在一个cpu的情况下,在同一个时间点,cpu只能执行一个代码,因为切换的很快,所以模拟出了多线程。

  • 线程就是独立的执行路径
  • 在程序运行时,即使没有自己创建线程,后台也会有多个线程,如主线程,gc线程
  • main()称之为主线程,为系统的入口,用于执行整个程序;
  • 在一个进程中,如果开辟了多个线程,线程的运行由调度器安排调度,调度器是与操作系统紧密相关的,先后顺序是不能人为的干预的。
  • 对同一份资源操作时,会存在资源抢夺的问题,需要加入并发控制;
  • 线程会带来额外的开销,如cpu调度时间,并发控制开销
  • 每个线程在自己的工作内存交互,内存控制不当会造成数据不一致

创建方式

  • Thread class(继承Thread类) 已经实现了runnable 不建议使用,避免oop单继承局限性
  • Runnable 接口(实现runnable接口) 灵活方便
  • callable接口 实现返回值,可以抛出异常

线程开启不一定立刻执行,cpu调度才开始执行

调用run方法会先执行完run才执行其他方法,而通过start开启线程会交替执行

并发问题

在多个线程同时访问同一个资源时,会出现紊乱,导致线程不安全。

静态代理

静态代理模式:

​ 真实对象和代理对象都实现同一个接口

​ 代理对象要代理真实角色

好处:

​ 代理对象可以做很多真实对象无法完成的操作

​ 真实对象专注于做自己的事情

多线程实现的底层原理!

Lambda表达式

  • lambda表达式只有一行代码时才可以直接简化为一行,若有多行,需要用代码块的形式来简化。即大括号包围。
  • 前提为函数式接口,即接口中只有一个方法
  • 多个类型也可以去掉参数类型,要去都去掉

线程停止

  1. 建议线程正常停止,利用次数,不建议死循环
  2. 建议使用标志位,flag = false,则终止线程运行
  3. 不推荐使用JDK提供的stop()、destroy()方法

线程休眠

  1. 利用网络延时放大错误的发生性
  2. thread.sleep();

线程礼让

线程礼让不一定成功,看cpu的调用

thread.yield();

线程强制执行

“线程插队”join

强制插入到第一个线程,必修在其执行结束才可以执行其他线程

线程的状态

  • new
  • runnable
  • timed_waiting
  • terminated
  • blocked

线程的优先级

先设置优先级再启动线程

并不是优先级高的一定先执行,会出现性能倒置的情况

线程的同步

在需要同步的方法前添加synchronized关键字,各个线程排队执行

synchronized锁的只是this对象,并不会对其他上锁,所以需要同步块

需要上锁的对象是需要进行增删改的对象,在run方法中对对应的对象上锁,使用同步块的方式

lock锁

  • Lock是显式锁(手动开启和关闭锁,别忘记关闭锁)synchronized是隐式锁,出了作用域自动释放

  • Lock只有代码块锁,synchronized有代码块锁和方法锁

  • 使用Lock锁,JVM将花费较少的时间来调度线程性能更好。并且具有更好的扩展性(提供更多的子类)

  • 优先使用顺序:
    Lock >同步代码块 (已经进入了方法体,分配了相应资源)>同步方法(在方法体之外)

线程协作

生产者消费者问题

  1. 管程法

并发协作模型“生产者/消费者模式”—>管程法

生产者:负责生产数据的模块(可能是方法,对象,线程,进程);

消费者:负责处理数据的模块(可能是方法,对象,线程,进程)缓冲区;

消费者不能直接使用生产者的数据,他们之间有个“缓冲区

生产者将生产好的数据放入缓冲区,消费者从缓冲区拿出数据

  1. 信号灯法

使用一个标志位flag来标识是否通知或等待达到线程通信的目的

线程池

JDK 5.0起提供了线程池相关API

ExecutorService 和 Executors

  • ExecutorService: 真正的线程池接口。常见子类ThreadPoolExecutor

  • void execute(Runnable command): 执行任务/命令,没有返回值,一般用来执行Runnable

  • Futuresubmit(Callable task): 执行任务,有返回值,一般又来执行Callable

  • void shutdown():关闭连接池

  • Executors:工具类、线程池的工厂类,用于创建并返回不同类型的线程池

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值