多线程详解

多线程

进程

进程 就是一个线程的集合

线程

线程都在main函数里面 main是用户创建守护线程

多线程创建

方式一

通过继承Thread重写 run方法 在主线程 调用start 实现并发交替执行

方式二

实现runnable接口

启动线程传入目标对象+thread对象.start

推荐使用 避免了单继承的局限性 灵活方便 方便同一个对象被多个线程使用

方式三

callable

实现callable接口 需要返回值类型 

重写call方法需要抛出异常

创建目标对象

创建执行任务 ExecutorService service=Executors.newFixedThreadPool(3);
提交执行  Future<Boolean> r1= (Future<Boolean>) service.submit(t1);
获取结果  boolean rs1=r1.get();
关闭   service.shutdownNow();

静态代理

静态代理模式总结:
  真实对象和代理对象都要实现同一个接口
  代理对象要代理真实角色
  
 好处
   代理对象可以做很多真实对象做不了的事情
   而真实对象可以专注的做自己的事情

lambda表达式

接口里面只有一个方法才可以使用 函数式接口

总结

lambda 表达式只能有一行代码的情况下才能简化成为一行 如果有多行 那么就用代码块包裹

前提是函数式接口

多个参数可以可以去掉参数类型 但是要带上括号

停止线程

利用标识位 标识位false 使其停止 不要用官方的stop 官方不建议使用的

礼让线程

礼让就是我进去了 模块 然后退出重新进行就绪 然后如果cpu调度另外一个就礼让成功

Join合并线程

就是将这个线程执行完成后才能执行其他线程 堵塞 插队

Priority线程优先级

可以设置线程优先执行 但主要还是看调度

Daemon守护线程

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

虚拟机必须确保正常线程执行完毕

虚拟机是不需要等待守护线程

比如 后台日志 gc …

线程同步

同步的安全性 线程+锁来解决同步的安全性 synchronize 锁机制

synchronize 关键字

它是一种 锁的机制 对象会得到一把锁 然后去访问 访问结束 本对象释放锁 然后才能下个用户访问

缺点 如果锁了整个类 会导致资源低效

synchronize 代码块 默认锁的是本身 this 谁去做crud操作了就锁谁

锁的对象 就是变化的量 就是要加锁的

CopyOnWriteArrayList 并发包下 线程安全 里面用显式的锁机制

死锁 Dead Lock

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

总结 解决方法 我们只要想办法破其中的任意一个或多个条件就可以避免死锁的发生


LOCK(锁)

ReentrantLock 可重试锁

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

线程消费者与生产者

方法名作用
wait ( )表示线程一直等待直到其他线程通知,与sleep不同,会释放锁
wait(long timeout)指定等待的毫秒数
notify( )唤醒一个处于等待的状态
notifyAll( )唤醒同一个对象上所有调用wait方法的线程,优先级别高的线程优先调度

注意:均是object类的方法 都只能在同步方法或者同步代码块中使用,否则会抛出异常IIIegaImonitorstateexception

解决线程通信方法

并发协助模型 “生产者/消费者模式”----->管理法(1)

  • 生产者 负责生产数据的模型(可能是方法 对象 线程 进程)
  • 消费者 负责处理数据模型(可能是方法 对象 线程 进程)
  • 缓冲区 消费者不能直接使用生产者的数据 他们之间有个缓冲区

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


解决方式2

并发协助模型 生产者/消费者—》信号灯法

线程池

  • 背景 经常创建与销毁使用量非常大的资源 比如并发情况下的线程,对性能影响很大

  • 思路:提前创建好多个线程 放入线程池 使用时直接获取,使用完放回池中 可以避免频繁创建销毁 实现重复利用,类似与生活中的交通工具

  • 好处

    • 提高响应的速度(减少了创建新线程的时间)
    • 降低资源消耗(重复利用线程池创建线程,不需要每次都创建)
    • 便于线程管理(。。.)
    • corePoolSize 线程大小
    • maxximumPoolSize 最大线程数
    • keepAliveTime:线程没有任务时最多保持多长时间会终止
  • jdk5.0开始提供了线程池相关的ApI:ExecutorServie和Executors

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

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

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

  • void shutdown():关闭线程池

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值