java多线程

  1. 两种方法创建线程

    1. 继承Thread 类并覆盖 run方法。
    2. 通过实现Runnable接口创建。
  2. 线程的生命周期

    image-20210507225842877

  3. 线程调度

    1. 等待

      方法说明
      void wait()导致当前的线程等待,直到其他线程调用此对象的 notify()方法或 notifyAll()方法。
      void notify()唤醒在此对象监视器上等待的单个线程。
      void notifyAll()唤醒在此对象监视器上等待的所有线程。
      注意
      必须从同步环境内调用wait()、notify()、notifyAll()方法。
      线程不能调用对象上等待或通知的方法,除非它拥有那个对象的锁。
      在多数情况下,最好通知等待某个对象的所有线程。
    2. 睡眠

      方法说明
      Thread.sleep(long millis)静态方法强制当前正在执行的线程休眠(暂停执行),以“减慢线程”。
      注意
      线程睡眠是帮助所有线程获得运行机会的最好方法。
      线程睡眠到期自动苏醒,并返回到可运行状态,不是运行状态。sleep()中指定的时间是线程不会运行的最短时间。因此,sleep()方法不能保证该线程睡眠到期后就开始执行。
      sleep()是静态方法,只能控制当前正在运行的线程。
    3. 让步与优先级

      方法说明
      t.setPriority(5);暂停当前正在执行的线程对象,并执行其他线程。MIN:1 / DEF:5 / MAX:10
      注意
      线程总是存在优先级,优先级范围在1~10之间。
      JVM线程调度程序是基于优先级的抢先调度机制。在大多数情况下,当前运行的线程优先级将大于或等于线程池中任何线程的优先级。但这仅仅是大多数情况。
      当设计多线程应用程序的时候,一定不要依赖于线程的优先级。因为线程调度优先级操作是没有保障的,只能把线程优先级作用作为一种提高程序效率的方法,但是要保证程序不依赖这种操作。
      当线程池中线程都具有相同的优先级,调度程序的JVM实现自由选择它喜欢的线程。这时候调度程序的操作有两种可能:一是选择一个线程运行,直到它阻塞或者运行完成为止。二是时间分片,为池内的每个线程提供均等的运行机会。
      方法说明
      Thread.yield()暂停当前正在执行的线程对象,并执行其他线程。
      注意
      yield()应该做的是让当前运行线程回到可运行状态,以允许具有相同优先级的其他线程获得运行机会。
      使用yield()的目的是让相同优先级的线程之间能适当的轮转执行。但是,实际中无法保证yield()达到让步目的,因为让步的线程还有可能被线程调度程序再次选中。
    4. 线程合并

      方法说明
      t.join();让一个线程B“加入”到另外一个线程A的尾部。在A执行完毕之前,B不能工作。
      t.join(5000);让线程等待指定毫秒,如果超过这个时间,则停止等待,变为可运行状态。
    5. 守护线程

      方法说明
      setDaemon(boolean on)将该线程标记为守护线程或用户线程。当正在运行的线程都是守护线程时,Java虚拟机退出。 参数:on - 如果为true,则将该线程标记为守护线程。
  4. 同步锁

    关键字说明
    synchronized使用synchronized关键字同步方法或代码。
    注意
    Java中每个对象都有一个内置锁。
    当程序运行到非静态的synchronized同步方法上时,自动获得与正在执行代码类的当前实例(this实例)有关的锁。
    获得一个对象的锁也称为获取锁、锁定对象、在对象上锁定或在对象上同步。
    当程序运行到synchronized同步方法或代码块时才该对象锁才起作用。
    一个对象只有一个锁。所以,如果一个线程获得该锁,就没有其他线程可以获得锁,直到第一个线程释放(或返回)锁。
    释放锁是指持锁线程退出了synchronized同步方法或代码块。
    1. 同步锁会对****多线程情况****下的程序执行效率产生一定的影响
    2. 同步锁只能用在代码块或者方法上,不存在类的同步和属性的同步。
    3. 线程睡眠时,它所持的任何锁都不会释放。
    4. 同步代码块的使用
      1. 把会受到并发影响的都通通包裹起来
      2. 同步代码块之前可以做一些具有共性的操作,或者不影响数据的操作;同步代码块之后的内容,会受到同步等待的影响
      3. 某一个线程,可以同时拥有多个对象的锁;同时拥有多个对象锁的情况下,有可能会产生****死锁****,虽然这个概率极低,但是只要有这种可能性存在,那么就必须考虑周全。避免发生死锁,需要时刻记着多个对象持锁的顺序。
      4. 静态方法的同步代码块,同步的是类,不是对象
      5. 静态和非静态同步最好不要混用
  5. 锁提供了两种主要特性:互斥(mutual exclusion) 和可见性(visibility)。互斥即一次只允许一个线程持有某个特定的锁,因此可使用该特性实现对共享数据的协调访问协议,这样,一次就只有一个线程能够使用该共享数据。可见性要更加复杂一些,它必须确保释放锁之前对共享数据做出的更改对于随后获得该锁的另一个线程是可见的 。如果没有同步机制提供的这种可见性保证,线程看到的共享变量可能是修改前的值或不一致的值,这将引发许多严重问题。

  6. volatile

    关键字说明
    volatilevolatile 变量可以被看作是一种 “程度较轻的 synchronized”;与 synchronized 块相比,volatile 变量所需的编码较少,并且运行时开销也较少,但是它所能实现的功能也仅是 synchronized 的一部分。
    注意
    volatile 变量不能用作线程安全计数器,例如:增量操作(x++)
    然而,如果将值调整为只从单个线程写入,那么可以忽略第一个条件。
    大多数编程情形都会与这两个条件的其中之一冲突,使得 volatile 变量不能像 synchronized 那样普遍适用于实现线程安全。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

隐 风

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值