Java 并发基础

一、进程与线程

程序:一段静态的代码,一组指令的有序集合,它本身没有任何运行的含义,它只是一个静态的实体,是应用软件执行的蓝本

进程:  是程序的一次动态执行,对应着从代码的加载、执行、结束的完整过程,是有生命周期的。

  • 进程包括就绪状态、执行状态、阻塞状态

线程:线程是进程的一个实体、是CPU 调度和分派的基本单位,是比进程更小的能独立允许的基本单位

1.创建并启动一个线程

new Thread().start();

2.重写run 方法并创新一个线程

Runnable runnable = ()->{System.out.println("重写 run ...");};
new Thread(runnable).start();

3.线程组 

  • main 线程的ThreadGroup 称为 main
  • 构造一个线程时候如果没有显示指定 ThreadGroup ,那么它将会和父线程一个Group
  • ThreadGroup 不能管理Thread,可以对Thread 组织

4.进程内存与线程数量

进程内存 =堆内存 + 线程数量 * 栈内存

5.守护线程

一类特殊的线程,也称后台线程(如垃圾回收线程)。通过 setdAEMON 方法可以设置线程为守护线程

  • 设置线程为守护线程必须再在线程启动之前,否则会报错
  • 守护线程能够自动结束生命周期

二、线程 API

1.sleep()

可以指定线程的休眠时间,在 jdk1.5 之后 TimeUnit 替代Thread.sleep()

2.yield()

调用会提示调度器当前线程愿意放弃当前 cpu 资源,如果cpu 资源足够,则会忽略

3.setPriority()

设置线程的优先级(1~10),会产生弊端,空闲占用资源

4.join()

与 sleep 方法一样,是可中断的方法。会使当前宣布从永远的等待下去,直到被中断或者join 的线程执行结束

5.wait()

  • wait 方法必须拥有当前对象的 monitor ,在同步块中使用
  • 一旦执行wait,则放弃该对象的 monitor,其他线程继续抢占
  • 是可断的方法
  • 与sleep 的区别
    • sleep 不会放弃 monitor ,wait 放弃
    • sleep 属于线程特意的方法,wait 属于 Object 方法
    • 都是可中断方法,都会使得线程进入阻塞状态
    • sleep 阻塞后自动恢复,wait 需要 notify / notifyAl

6.notify / notifyAll

  object 的方法

三、线程安全

synchronized 关键字

  • synchronized 是一种排他机制,同一时间只能有一个线程执行操作
  • 包括了 monitor enter 和 monitor exit 两个 jvm 指令
  • 严格遵守 happens-before , 一个 monitor exit 之前一定有一个 monitor enter
  • 如果 monitor 的计数器 为0 ,意味着 monitor 的锁还未被获得,如果获得则 +1
  • 如果已经拥有monitor 的锁,重新获取,则再次 +1 ,monitor exit 则计数器 -1

四、发生死锁

  1. 交叉锁
  2. 内存不足
  3. 一问一答
  4. 数据库锁
  5. 文件锁
  6. 死循环

JVM 线程内存模式

 参考文章:http://ifeve.com/java-concurrency-thread-directory/

原文地址:https://www.cnblogs.com/bytecodebuffer/p/10535457.html