今日份学习: 多线程

多线程原理

为什么需要多线程?

  • CPU/内存/IO的巨大性能差异

  • 多核CPU的发展



  • 一个线程表现的本质就是多出来一套完整的方法栈

    • 优点:多个执行流,并发执行
    • 缺点:
      • 占用资源:每个线程有独立的方法栈
      • 慢,切换上下文
    • 能不能让上下文切换尽可能少?
      • 协程 - 用户态线程

Thread

  • Thread类的每一个实例代表一个JVM中的线程

只有Thread是线程,其他的都不是线程(注释中提到),Runnable和Callable是一个任务,一小段代码

Runnable / Callable

  • Runnable代表一个任务
    • 可以被任何一个线程执行
  • Callable解决了Runnable的一些问题
    • Runnable不能返回值
    • Runnable不能抛出checked exception

Runnable jdk1.0

Callable jdk1.5

笔记

  • 多线程缺点:

    1. 代码复杂,变得很难理解
    2. 线程的互相交互和访问共享变量会引发各种问题,包括死锁等
  • try-catch只会捕获当前线程的异常

  • 异常的抛出是顺着方法栈往外抛的

  • 线程的底部要么是main()方法,要么是Thread.run()方法

“在可计算性理论里,如果一系列操作数据的规则(如指令集、编程语言、细胞自动机)可以用来模拟单带图灵机,那么它是图灵完备的。

  • 当两个线程运行的时候,方法栈的所有东西都是私有的,其他的都是公有的。

Volatile

  • 线程模型:

每一个线程可以有一个主内存的变量的副本,cpu定期同步回内存。

volatile的保证

  • 可见性,并非原子性
    • 写入volatile变量会直接写入主内存
    • 从volatile变量读取会直接读取主内存
    • 非常弱的同步机制
  • 禁止指令重排
    • 编译器和处理器都可能堆指令进行重排,导致问题
  • 有同步的时候无需volatile
    • synchronized/Lock/AtomicInteger




JUC:java.util.concurrent 并发工具包

  • 同步:synchronized
  • 协同:wait() / notify() / notifyAll()

synchronized

  • synchronized

    • Java语言级的支持,1.6之后性能及大提高
      • 字节码层面的实现:monitorenter / monitorexit
    • 锁住的是?
      • 对象
      • 如果是静态方法,那么锁住的是该类的class
      • 如果是非静态方法,那么锁住的是this对象
  • 缺点

    • 死板。比如:不能查看是否有别人拿到了锁对象。

    • 只有悲观锁、排他锁,没有乐观锁、共享锁

一定要和一个对象(monitor,监视器)协同

面试题:wait和sleep有什么区别?

  • wait() 之后锁对象就会被释放
  • 如果已经获取了锁对象,那么sleep() 之后不会释放锁对象。如果没获取锁对象,那么不关sleep() 什么事。。。

猜你喜欢

转载自www.cnblogs.com/pipemm/p/12498789.html