线程基础知识点

一、
1. 创建方式

A: 通过继承Thread来创建线程

B: 通过实现 Runnable 接口来创建线程

2. 线程六种状态

NEW(初始):线程被创建后尚未启动。由于一个线程实例只能够被启动一次,因此一个线程只可能有一次处于该状态。

RUNNABLE(运行):包括了两个状态:Running和Ready,前者标识处于该状态的线程可以被线程调度器进行调度而使之处以RUNNABLE状态。后者标识处于该状态的线程正在运行。
                               执行Thread.yield()的线程,它能让当前线程由RUNNING转换为READY.从而让其它具有相同优先级的等待线程获取执行权;
                               但是,并不能保证在当前线程调用yield()之后,其它具有相同优先级的线程就一定能获得执行权;也有可能是当前线程又进入到“运行状态”继续运行!

BLOCKED(阻塞):线程阻塞于锁。一个线程发起一个阻塞式I/O操作后 或者申请一个有其他线程持有的独占资源(比如锁)时,相应的线程会处于该状态。
处于BLOCKED状态的线程并不会占用处理器资源。 当阻塞式I/O操作完成后,或者 线程获得了其申请的资源,该线程状态又可转换为
RUNNABLE。

WAITING(等待):一个线程执行了某些特定方法只有就会处于这种等待其他线程执行另外一些特定操作的状态。
                           能够使其执行线程变更为WAITING状态的方法包括:Object.wait()、Thread.join()和LockSupport.park(Object)。
                           能够使相应线程从WAITING变更为RUNNABLE的相应方法包括:Object.notify()/notifyAll()和LockSupport.unpark(Object))。

TIME_WAITING(超时等待):该状态和WAITING类似,差别在于该状态线程处于带有时间限制的等待状态,它可以在指定的时间内自行返回。

TERMINATED(终止):该线程已经执行完毕。

3.Synchronized:

synchronized关键字可以作为函数的修饰符,也可作为函数内的语句,也就是同步方法和同步语句块,synchronized可作用于instance变量、object reference(对象引用)、static函数和class literals(类名称字面常量)身上。
* 无论synchronized关键字加在方法上还是对象上,它取得的锁都是对象,而不是把一段代码或函数当作锁――
而且同步方法很可能还会被其他线程的对象访问。
* 每个对象只有一个锁(lock)与之相关联。
* 实现同步是要很大的系统开销作为代价的,甚至可能造成死锁,所以尽量避免无谓的同步控制。
缺陷:
    a、无法控制阻塞时长
    b、阻塞不可中断
同步类型
a、同步代码块
      synchronized(锁对象){
              需要被锁的代码//线程只有拿到了锁对象,才能执行这里的代码!!!换言之,
              这里的代码如果执行了,说明该线程拿到了锁对象,其他线程不能拿到该锁对象
      }
      注意:多个线程必须使用同一个锁对象,要不然锁无效

同步方法
      a. public synchronized void show(){}               //普通方法的锁是this
      b.  public static synchronized void show(){}    //静态方法的锁是当前类的字节码文件对象 类名.class
注意问题
       a. 多个线程必须使用同一个锁对象,要不然锁无效
       b. 同步代码块锁可以是任意对象
       c. 同步方法的锁是this
       d. 静态方法的锁是当前类的字节码文件对象 类名.class 
二、

串行、并发与并行


    a: 串行 如:多个车辆行驶在一股车道上。

    b: 并发 如:多个车辆行驶在多股车道上,并驾齐驱。 并发的极致就是并行。由于处理器可以实现使用时间片(time-sclie)分配技术来实现在同一段时间内运行多个线程,因此一个处理器即可实现并发。

    C: 并行 并行需要靠多个处理器在同一时刻各自运行一个线程来实现。

 竞态

   a:   现象: 多线程编程中经常遇到一个问题就是对于同样的输入,程序的输出有时候正确有时候错误。对于这种一个计算结果的正确性与时间有关的现象被称之为静态(RaceCondition)。

   b:   解释竞态的结果: 状态变量:既类的实例变量、静态变量。 共享变量:即可以被多个线程共同访问的变量。

   c:  如何避免竞态:

      1.使用局部变量而非状态变量,就不会产生静态。

      2.添加synchronized关键字,使其修饰的方法在任何一时刻只能够被一个线程执行。这使得该方法涉及的共享变量在任一时刻只能够有一个线程访问(读、写),从而避免方法交错执行而导致的干扰消除了静态。

线程安全性

    a: 如果一个类在单线程环境下运行正常且在多线程环境下使其用方不改变的情况下也能运作正常,那么我们称其实线程安全,反之即非线程安全的。
    b: 一个类如果能够导致竞态,那么它是非线程安全的。而一个类如果是线程安全的,那么它不会导致竞态。
    c: java标准库中一些类如ArrayList、HashMap和SimpleDateFormat都是非线程安全的。如多个线程共享一个HashMap实例,可能会产生数据脏度也可能发生死锁,造成内存飙升100%的问题。

死锁

    a: 互斥条件:指进程对所分配到的资源进行排它性使用,即在一段时间内某资源只由一个进程占用。如果此时还有其它进程请求资源,则请求者只能等待,直至占有资源的进程用毕释放。
    b: 请求和保持条件:指进程已经保持至少一个资源,但又提出了新的资源请求,而该资源已被其它进程占有,此时请求进程阻塞,但又对自己已获得的其它资源保持不放。
    c: 不剥夺条件:指进程已获得的资源,在未使用完之前,不能被剥夺,只能在使用完时由自己释放。
    d: 环路等待条件:指在发生死锁时,必然存在一个进程——资源的环形链,即进程集合{P0,P1,P2,···,Pn}中的P0正在等待一个P1占用的资源;P1正在等待P2占用的资源,……,Pn正在等待已被P0占用的资源。
原 子 性:

            对于涉及共享变量访问的操作,若该操作从其执行线程以外的任意线程来看是不可分割的,那么该操作就是原子操作,称其为具有原子性。
不可分割:

        其中一个含义是指访问(读、写)某个共享变量的操作从其执行线程以外的任何线程来看,该操作要么已经执行结束要么尚未发生,即其它线程不会"看到"该操作执行了部分的中间效果。

原子操作:

             仅涉及局部变量访问的操作无所谓是否原子性, 原子操作是从该操作以外的执行线程以外的线程来描述的,也就是说只有在多线程环境下有意义。

实现原子性(java有两种方式来实现原子性)

    a. 使用锁(Lock)。锁具有排他性,能够保障一个共享变量在任意一个时刻只能够被一个线程访问。
    b. 利用处理器提供的专门CAS(Compare-and-Swap)指令,CAS指令实现原子性的方式与锁实现方式实质上是相同的,差别在于锁通常是在软件层次实现,
        而CAS直接在硬件(处理器和内存)这一层次实现,可被看做"硬件锁"。
 写操作的原子性: 在Java中long型和double型以外的任何类型的变量的写操作都是原子操作,即基础类型(long/double除外,仅包括byte、boolean、short、char、
                              float、int)的变量和引用性变量的写操作都是原子的。可以通过使用volatile关键字使对变量value的写操作具有原子性。
读操作的原子性: Java中针对任何变量的读操作都是原子操作。

扩展: 原子操作 + 原子操作 = 原子操作? NO

       如: 对于共享int变量a和b初始值都为0,假设线程A执行如下操作:
       a = 1; //语句1
       b = 2; //语句2
       显然,语句1和2都是原子操作,但在线程A执行完语句1之后和在执行语句2之前的这一刻,另外一个线程B可以读取变量a和b的值。那么
       此刻线程B读取到a和b的值分别是1和0,也就是说它读取到了线程A所执行的中间结果,这有悖于原子操作不可分割的特效。因此,原子操作+原子操作=非原子操作

可见性: 指一个线程对共享变量的更新的结果对于读取相应共享变量的线程而言是否可见的问题。多线程程序在可见性方面存在问题意味着某些线程读取到了旧数据。

如何保证可见性呢?
        volatile关键字提示编译器被修饰的变量可能被多个线程共享,以阻止编译器做出可能导致程序运行不正常的优化。
        另一个作用是杜宇一个volatile关键字修饰的变量会使相应的处理器执行刷新处理器缓存的动作,从而保障了可见性。

转载于:https://www.cnblogs.com/Mr-Zqd/p/10510922.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值