线程总结 1.散知识点

0.背景知识点:

1.什么是上下文切换:

前线程使用完时间片后,就会处于就绪状态并让出 CPU,让其他线程占用,这就是上下文切换,从当前线程的上下文切换到了其他线程.

2.什么是线程死锁:

线程a持有资源1.申请2

                               线程b持2,申请1

3.线程死锁的必备要素

1.互斥:线程对所分配的资源的排他性控制

2.不可剥夺:a在使用1的时候,不能被其他线程夺走,只能自己释放

3.请求保持:a请求2不得被阻塞的时候,保持对1的不释放

4.循环等待:

指在发生死锁时,必然存在一个线程请求资源的环形链,即线程集合 {T0,T1,T2,…Tn}中的 T0 正在等待一个 T1 占用的资源,T1 正在等待 T2 占用的资源,以此类推,Tn 正在等待己被 T0 占用的资源。

5.线程的主要方法:

1.start()用来启动一个线程

2.run()

Thread threadB = new Thread(new Runnable() { //创建线程 1
    @Override
    public void run() {

3.sleep方法

  sleep(long millis)    //参数为毫秒
  sleep(long millis,int nanoseconds)   //第一参数为毫秒,第二个参数为纳秒

4.yield方法线程让步

class ThreadA extends Thread {
    public void run() {
        for (int i = 0; i < 10; i++) {
            System.out.println("ThreadA--" + i);
            Thread.yield();
        }
    }
}

Thread中yield方法 - 劈天造陆 - 博客园 (cnblogs.com)

5.interrupt方法的

6.interrupted方法 此方法首先调用isInterrupted方法,而isInterrupted方法是一个重载的native方法 

 用来测试线程是否已经中断

 public boolean isInterrupted() {
        return isInterrupted(false);
    }

7.join方法有三个重载版本:

  join()
  join(long millis)    //参数为毫秒
  join(long millis,int nanoseconds)   //第一参数为毫秒,第二个参数为纳秒
  eg: thread1.join();

8.stop()弃用

9.destory()弃用

10.对属性进行设置的方法

        1)getId

  用来得到线程ID

  2)getName和setName

  用来得到或者设置线程名称。

  3)getPriority和setPriority

  用来获取和设置线程优先级。

  4)setDaemon和isDaemon

  用来设置线程是否成为守护线程和判断线程是否是守护线程。

参考:java.lang.Thread类详解 - Ryan520 - 博客园 (cnblogs.com)

6.守护线程

daemon 线程(守护线程〉和 user 线程(用户线程)。

守护线程定义:所谓守护线程,是指在程序运行的时候在后台提供一种通用服务的线程。比如垃圾回收线程就是一个很称职的守护者,并且这种线程并不属于程序中不可或缺的部分。

而 Java 中的守护线程是 JVM 级别的,当 JVM 中无任何用户进程时,守护进程销毁,JVM 退出,程序终止

public class DemoTest {
    public static void main(String[] args) throws InterruptedException {
        Thread threadOne = new Thread(new Runnable() {
            @Override
            public void run() {
                //代码执行逻辑
            }
        });
        threadOne.setDaemon(true); //设置threadOne为守护线程
        threadOne. start();
    }
}
//thread.setDaemon (true) 必须在 thread.start () 之前设置,否则会跑出一个 //llegalThreadStateException 异常。你不能把正在运行的常规线程设置为守护线程;
//在 Daemon 线程中产生的新线程也是 Daemon 的;
//守护线程应该永远不去访问固有资源,如文件、数据库,因为它会在任何时候甚至在一个操作的中间发生
//中断

7.线程的六个state

public enum State{

    NEW,

    RUNNABLE,

    BLOCKED, //处于blocked状态的线程还是会去竞争锁的,cpu有时间,竞争到,执行

    WAITING,  //不去竞争锁,被动的等通知

    TIMED_WAITING,//超时等待

    TERMINATED,

}

1.ThreadLocal 

ThreadLocal 是 JDK 包提供的,它提供了线程本地变量,也就是如果你创建了一个 ThreadLocal 变量,那么访问这个变量的每个线程都会有这个变量的一个本地副本。当多个线程操作这个变量时,实际操作的是自己本地内存里面的变量,从而避免了线程安全问题

方法

1.set

   ThreadLocal<String> localVariable = new ThreadLocal<> () ;
        localVariable.set("Hello World");

set 方法可以设置任何类型的值,

 2.get 

        localVariable.set("Hello World");
        System.out.println(localVariable.get());

3.ThreadLocal remove 

       localVariable.set("Hello World");
        System.out.println(localVariable.get());
        localVariable.remove();
        System.out.println(localVariable.get());

        //清除成功之后没有变量值

多线程下的 ThreadLocal

 static ThreadLocal<String> local = new ThreadLocal<>();  

  public static void main(String[] args){

  Thread threadOne = new Thread(new Runnable() {

  Thread threadOne = new Thread(new Runnable() {        

    @Override             public void run() {

        Thread threadTwo = new Thread(new Runnable() {        

    @Override             public void run() {

2.锁

0.多线程锁的分类:

1.悲观锁

悲观锁指对数据被外界修改持保守态度,认为数据很容易就会被其他线程修改(很悲观),所以在数据被处理前先对数据进行加锁,并在整个数据处理过程中,使数据处于锁定状态。

Java 中的 synchronized 关键字就是一种悲观锁

2.乐观锁:

 乐观锁是相对悲观锁来说的,它认为数据在一般情况下不会造成冲突,所以在访问记录前不会加排它锁,而是在进行数据提交更新的时候,才会正式对数据冲突与否进行检测。

CAS 原理即是乐观锁技术

Compare And Swap 比较和交换

CAS 主要包含三个操作数,内存位置 V,进行比较的原值 A,和新值 B。

当位置 V 的值与 A 相等时,CAS 才会通过原子方式用新值 B 来更新 V,

3.公平锁和非公平锁

是否先到先得

ReentrantLock:ReentrantLock 提供了公平和非公平锁的实现。

4.独占锁和共享锁

独占锁:保证任何时候都只有一个线程能得到锁,ReentrantLock 就是以独占锁方式实现的。(是一种悲观锁)

共享锁:则可以同时由多个线程持有,例如 ReadWriteLock 读写锁,它允许一个资源可以被多线程同时进行读操作。

 5.自旋锁

资源被占用的时候不马上阻塞自己,而是多次尝试获取,默认次数是10

锁1: synchronized (原子,顺序,内存可见)

1.互斥条件,用同一把锁

2.静态方法锁类的所有对象

3.同一线程支持重入

4.修饰举例(方法,静态方法,代码块)

1).修饰实例方法

  public synchronized void increase() throws InterruptedException {
        sleep(1000);

2).静态方法

public static synchronized void increase() throws InterruptedException {
        System.out.println(Thread.currentThread().getName() + "获取到锁,其他线程在我执行完毕之前,不可进入。" );
        sleep(1000);
        count++;
        System.out.println(Thread.currentThread().getName() + ": " + count);
    }

3).代码块
    static final Object objectLock = new Object(); //创建一个对象锁
    public static void increase() throws InterruptedException {
        System.out.println(Thread.currentThread().getName() + "获取到锁,其他线程在我执行完毕之前,不可进入。" );
        synchronized (objectLock) {
            sleep(1000);
            count++;
            System.out.println(Thread.currentThread().getName() + ": " + count);
        }
    }
 

锁2: 关键字vloatile(保证变量的内存可见性,禁止指令重排序)

private volatile boolean  flag=false;

public class Student {
    private String name;

    public synchronized String getName() {
        return name;
    }

    public synchronized void setName(String name) {
        this.name = name;
    }
}

public class Student {
    private volatile String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

此时等价

详细讲解:

Java volatile关键字最全总结:原理剖析与实例讲解(简单易懂)_夏日清风-CSDN博客_java volatile

 不能用于非原子操作,eg:i++

锁3:lock类

1.lock类引入必要性,因为synchronized的顺序性,全部线程对一个资源进行读操作时,其他线程会进行等待

2.实现接口:

public interface Lock {
    void lock();  //获取锁
    void lockInterruptibly() throws InterruptedException; 
    //前线程未被中断,则获取锁
    boolean tryLock(); //获取空闲锁
    boolean tryLock(long time, TimeUnit unit) throws InterruptedException;
    void unlock();//如果锁在给定的等待时间内空闲,并且当前线程未被中断,则获取锁;
    Condition newCondition(); //如果锁在给定的等待时间内空闲,并且当前线程未被中断,则获取锁;
}


 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值