多线程初级

64 阅读2分钟

线程的生命周期

image.png

线程常见方法

start() 启动当前线程,表面上调用start方法,实际在调用线程里面的run方法。

  1. run()线程类继承Thread类或者实现Runnable接口的时候,都要重新实现这个run方法,run方法里面是线程要执行的内容。
  2. currentThread:Thread类中一个静态方法,获取当前正在执行的线程
  3. setName设置线程的名字
  4. getName读取线程名字
  5. join:当一个线程调用了join方法,这个线程就会被执行,它执行结束以后才可以去执行其余的线程。注意:必须先start,再join才有效
  6. sleep:Thread类中一个静态方法。是一个人为的阻塞方法。
  7. setDeamon:设置伴随线程。
  8. stop:停止线程。

设置优先级别

  1. 同优先级别的线程,采取的策略就是先到先服务,使用时间片策略
  2. 如果优先级别高,被cpu调度的概率就高
  3. 级别:1-10级,默认的级别为5

锁(同步监视器)

  1. 必须是引用数据类型,不能是基本数据类型
  2. 页可以创建一个专门的同步监视器,没有任何业务含义
  3. 一般使用共享资源做同步监视器即可
  4. 在同步代码块中不能改变同步监视器对象的引用。
  5. 尽量不要String和包装类Integer做同步监视器
  6. 建议使用final修饰同步监视器

同步代码块的执行过程

  1. 第一个线程来到同步代码块,发现同步监视器open状态,需要close然后执行其中的代码
  2. 第一个线程执行过程中,发生了线程切换(阻塞、就绪),第一个线程失去了cpu,但是没有开锁open。
  3. 第二个线程获取cpu,来到了同步代码块,发现同步监视器close状态,无法执行其中的代码,第二个线程也进入阻塞状态
  4. 第一个线程再次获取cpu,接着执行后续的代码,同步代码块执行完毕,释放锁open.
  5. 第二线程也再次获取cpu,来到了同步代码块,发现同步监视器open状态,拿到锁并且上锁,由阻塞状态进入就绪状态,再进入运行状态,重复第一个线程的处理过程(加锁)

强调:同步代码块中发生cpu的切换?能,但后续的被执行线程也无法执行同步代码块(因为锁依旧close)

  1. 方法中放入synchronized表示锁的是当前实例this
  2. 方法中放入 static synchronized表示锁的是当前字节码文件。