Java 多线程学习笔记

多线程能满足程序员编写高效率的程序来达到充分利用 CPU 的目的多线程在单个程序中同时运行多个线程完成不同的工作,称为多线程(提升整体处理性能)
一. 什么是线程?线程是程序的最小单位,相对独立的可调用单元,是 CPU 最小基本单位;
在同一个程序中不同的线程完成功能,称为多线程 。(软件中最小单位就是线程)
二. 线程、进程、程序的关系(☆)程序进程线程程序就是一段静态的代码,是应用程序的蓝本进程是正在运行的程序的实例:进程是程序的一次正常运行,从代码加载到最后一句代码的执行,整个过程就是进程的生命周期进程中独立、可调用的最小执行单元:线程是程序中一个单一的顺序控制流程

  • 程序与进程的关系:
    一个程序一般只有一个进程,但一个程序可以拥有多个进程
    一个进程只能属于一个程序
  • 进程与线程的关系:
    一个进程拥有多个线程,一个线程只能属于一个进程
    一个程序只有一个主线程
一个程序只有一个主线程:Java 应用程序中主线程就是main方法,其他的都是子线程
三. 线程的创建
  1. 创建一个类继承 Thread 类(多个线程分别完成自己的任务)
    Thread th = new Thread();th.start();
  2. 创建一个类实现一个 Runnable (多个线程共同完成同一个任务)
    Thread th = new Thread(new Runnable());th.start();
使用 Runnable 接口创建的线程,还是要借用 Thread 类来启动线程
线程是异步的,可以同时操作多个任务四. 线程的生命周期(☆)
  1. 创建:线程的构造
  2. 启动:线程对象调用start()方法
  3. 运行:占用CPU,进入run()方法
  4. 中断:在run()方法中,遇到sleep()wait()方法,线程就会中断,让出CPU资源
  5. 死亡:运行完run()方法
五. 线程的状态(☆)
  1. 新建状态(NEW):创建了一个线程对象,但是没有启动
  2. 就绪状态(RUNNABLE):线程对象调用了start()方法
  3. 运行状态(RUNNABLE):线程对象占用CPU,进入run()方法
  4. 阻塞状态(BLOCKED):线程对象放弃CPU,暂停运行,遇到sleep()方法
  5. 死亡状态(TERMINATED):线程运行完run()方法
六. 线程的休眠(sleep)与唤醒(interrupt)当一个线程对象在 sleep 的时候,可以用过interrupt()方法强制唤醒,唤醒后会抛出java.lang.InterruptedException
七. 线程常用方法方法描述start()启动线程(使线程处于就绪状态)run()线程占用CPU正在运行,业务逻辑写在此方法中setName()给线程设置名称getName()获取线程名称setPriority()设置线程的优先级别:1为最小、5为默认、10为最大getPriority()获取线程的优先级currentThread()获取当前正在运行的线程getState()获取线程状态sleep()线程的休眠interrupt()线程中断休眠isInterrupted()判断线程是否为中断状态isAlive()测试线程是否处于活动状态setDaemon()把线程设置为守护线程(当程序中其他守护线程结束时,该守护线程也会结束)isDaemon()判断线程是否为守护线程join()等待该线程终止yield()暂停当前正在执行的线程,并执行其他线程(包含了自己本身)八. 线程的同步
  1. 什么是线程不安全?
    多个线程改变同一个对象的同一个全局属性,就会造成线程不安全
  2. 线程不安全有三个必要条件?
    1. 必须是同一个对象
    2. 必须改变同一个全局属性
    3. 必须是多个线程操作
  3. 同步锁
    1. 在方法行增加 synchronized 关键字,增加同步关键字之后,方法调用变缓慢,变成重量级
    2. 同步方法(方法锁):在方法上面加 synchronized 关键字
    3. 同步代码块(对象锁):锁相对应的对象
    4. 类锁:synchronized(Student.class){}
    5. 可重入锁(ReentrantLock):锁具体的代码块
九. 线程的挂起(wait)与恢复(notifyAll)wait():线程挂起
notify():唤醒单个线程
notifyAll():唤醒所有线程
wait()方法不稳定必须要加上同步锁
以上三个方法全是 Object 类的方法
十. 单例模式(自始至终产生一个对象)(☆)
  1. 懒汉模式
    1. 构造私有化
      1. 声明一个静态的自身对象属性
      2. 提供静态方法,返回自身对象,方法必须加上synchronized关键字
  2. 恶汉模式
    1. 构造私有化
      1. 声明一个静态自身属性,并且实例化
      2. 提供一个静态方法返回自身对象
作用优点缺点始终保持一个实例节约内存空间,创建效率高容易造成线程不安全问题十一. 枚举枚举是 Java 中一种数据类型,相当于常量,但比常量的扩展性强
枚举类型存放在 JVM 的常量池中,永远不会被回收,除非程序关闭
枚举默认是单例,所以构造方法必须私有化
声明枚举的时候,必须固定好实例,枚举的实例必须事先声明
定义:public enum 枚举名称{}十二. 同步锁(sysnchronized)使用事项 (☆)
  1. 动态方法上的 synchronized 锁,锁的是当前对象
  2. 静态方法上的 synchronized 锁,锁的是当前类的字节码
  3. 动态方法与静态方法进行同步锁,那么锁同一个全局变量
  4. 同步方法中调用了wait()方法,会让出 CPU 并且释放锁,调用sleep()方法,只会让出 CPU 不会释放锁
  5. 同步锁必须锁同一样东西才会生效
十三. sleep 与 wait 区别 (☆)
  1. sleep 是 Thread 类中的方法,wait 方法是 Object 类的方法
  2. sleep 方法只会让出 CPU,不会释放锁
  3. wait 方法会让出 CPU 并且释放锁
  4. 使用 sleep 方法不需要结合同步锁,wait 方法一定要结合同步锁使用
  5. sleep 方法会根据参数设置的时间自然醒,wait 方法除了会根据参数设置的时间自然醒,还可以通过notify()notifyAll()唤醒
十四. 定时任务Timer:定时器
TimerTask:定时器任务
十五. 线程同步方式
  1. synchronized 关键字修饰的方法
  2. synchronized 关键字修饰的语句块
  3. volatile 关键字修饰的变量,多个变量访问时,可以保证最新值
  4. JDK 在java.util.concurrent包下提供了一把锁的机制,代码如下:
    // 可以放在任何地方进行同步锁Lock lock = new ReentrantLock();// 加锁lock.lock()// 解锁lock.unlock()
  5. 使用 ThreadLocal 管理全局变量,可以使单例对象多例属性,也称为:线程变量 。
    ThreadLocal通过set方法进行赋值,get方法取值
  6. 使用队列阻塞
  7. 使用原子变量实现线程同步
十六. 线程安全集合与线程不安全集合线程安全线程不安全StringBufferStringBuilderVectorArrayListHashTableHashMap作业
  1. 做一个简单的缓存机制,缓存中存储部分表的数据,使用数据时从内存中获取,不去查数据库
    1. 程序运行main方法时,把指定表的数据读取出来,存放到单例模式中的数据结构中(map)
    2. 查询数据时,直接从单例模式中获取表中的数据
    3. 每隔半小时,同步一次数据库与内存中的数据
什么样的数据适合放在缓存机制中?
  1. 经常被查询的数据
  2. 不会经常改变的数据,更新的频率不频繁
【Java 多线程学习笔记】本文来自博客园,作者:Schieber,转载请注明原文链接:https://www.cnblogs.com/xiqingbo/p/java-20.html