Java SE知识点总结(8:Java多线程)

目录

八:Java多线程

1、多线程概述

2、线程创建

1.线程创建的几种方式

2.继承Thread类

3.实现Runnable接口

4.实现Callable接口

5.静态代理模式

6.Lambda表达式

3、线程状态

1.线程礼让

2.线程强制执行

3.线程状态观测

4.线程优先级

5.守护线程

4、线程同步机制

1.线程同步

2.同步方法和同步块

3.死锁

4.Lock锁

5、线程通信

1.线程通信分析

2.解决方式


八:Java多线程

1、多线程概述

  1. 因为现实需求生活中是多任务的,因此引出了多线程

  2. 但是同一个时刻,单核cpu依旧是只做一件时期

  3. 一个进程里面有很多个线程,至少有一个线程(即是主线程)

  4. 多线程的调度,是cpu依靠调度算法调度的

  5. 线程就是独立的执行路径

  6. main线程,程序的入口

  7. 对同一份资源,会存在资源抢夺的问题,需要加入并发控制(上锁)

  8. 线程会带来额外的开销,如cpu调度时间,并发控制开销

2、线程创建

1.线程创建的几种方式

  1. 继承Thread类

  2. 实现Runnable接口(重点)

  3. 实现Callable接口(了解)

  4. 利用Lambda表达式

  5. spring boot异步注解

  6. 线程池

2.继承Thread类

Thread简介

  1. Thread类实现了Runnable接口

  2. 继承了Object类

Thread类使用步骤

  1. 继承Thread类

  2. 重写run方法(@Override)

  3. 调用start方法开启线程(不是立即执行的)

    //多线程案例1
    public class Demo extends Thread {
    ​
        @Override
        public void run() {
            for (int i = 0; i < 200; i++) {
                System.out.println("我在看代码-------" + i);
            }
        }
    ​
        public static void main(String[] args) {
            Thread thread1 = new Demo();
            thread1.start();
            for (int i = 0; i < 200; i++) {
                System.out.println("我在学习多线程-------" + i);
            }
        }
    }

3.实现Runnable接口

Runnable接口使用步骤

  1. 定义类实现Runnable接口

  2. 重写run方法

  3. 执行线程需要丢入Runnable接口的实现类(Thread类),调用start方法

    public class Demo implements Runnable {
    ​
        @Override
        public void run() {
            for (int i = 0; i < 2000; i++) {
                System.out.println("我在看代码-------" + i);
            }
        }
    ​
        public static void main(String[] args) {
            Demo demo = new Demo();
            Thread thread1 = new Thread(demo);
            thread1.start();
            for (int i = 0; i < 2000; i++) {
                System.out.println("我在学习多线程-------" + i);
            }
        }
    }//使用该方式会更加灵活,避免java的单一继承缺点,接口可以多继承

4.实现Callable接口

使用步骤

  1. 实现Callable接口,需要返回类型

  2. 重写call方法,需要抛出异常

  3. 创建目标对象

  4. 创建执行服务:ExecutorService ser = Executors.newFixedThreadPool(1);

  5. 提交执行:Future<Boolean> result1 = ser.submit(t1);

  6. 获取结果:boolean r1 = result1.get();

  7. 关闭服务:ser.shutdownNow();

    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.Future;
    //位于juc包下,属于并发编程领域

5.静态代理模式

6.Lambda表达式

3、线程状态

1.线程礼让

  1. 礼让线程,让当前正在执行的线程暂停,但不阻塞

  2. 将线程从运行态转换为就绪态

  3. 让cpu重新调度,礼让不一定成果!看cpu心情

  4. yield():线程让步方法

2.线程强制执行

  1. join合并线程,待此线程执行完成后,再执行其他线程,其他线程阻塞

  2. 可以想象成阻塞

  3. join():线程强制执行

3.线程状态观测

  1. 线程创建:新生,尚未启动的线程

  2. 线程就绪:start()方法执行后,进入就绪队列,不会立即开始执行

  3. 线程运行:cpu调度后

  4. 线程阻塞:I/O阻塞,sleep()线程睡眠,notify()线程唤醒

  5. 线程死亡:run方法执行完毕

  6. state方法观测线程状态

4.线程优先级

  1. getPriority():得到线程的优先级(默认为5)

  2. setPriority():设置线程的优先级

  3. 优先级就是线程被cpu调度的优先级(1——10)

  4. 优先级越高,线程被调度的可能性越大

  5. 高优先级的不一定先调度

5.守护线程

  1. 线程分为用户线程和守护线程

  2. 虚拟机必须确保用户线程执行完毕(main主线程,其他用户创建的线程)

  3. 虚拟机不用等待守护线程执行完毕(GC垃圾回收线程,日志log线程,内存监控线程等等)

4、线程同步机制

1.线程同步

  1. 线程同步的引出就是多个线程操作同一个资源

  2. 并发:同一个对象(对象锁)被多个线程同时操作

  3. 解决方案

  4. 第一步:要访问对象的线程进入这个对象的等待池,形成对象(进入对象等待池)

  5. 第二步:线程拿到对象资源锁(拿到锁资源)

  6. 注意:多个锁资源有可能造成死锁问题

  7. synchronized锁:一种对象锁,使用方便

  8. 上锁会造成资源浪费,不上锁会产生线程安全性问题

2.同步方法和同步块

同步方法

  1. 方法加上了synchronized关键字就会变为同步方法

  2. 缺陷,一个大的synchronized方法会影响效率

  3. 原因:一个方法里面有A代码(只读);B代码(修改)

  4. 修改的代码才需要上锁,才会产生线程安全性问题

同步块

  1. synchronized(obj){ }

  2. obj:称为同步监视器

  3. obj可以是任何对象,默认为this(本个对象,就是这个自己;在反射,类加载机制中会详细介绍)

同步监视器执行过程

  1. 第一个线程访问:锁定同步监视器,执行其中代码

  2. 第二个线程访问:发现同步监视器被锁定,无法访问,线程阻塞

  3. 第一个线程访问完毕:解锁同步监视器

  4. 第二个线程访问:发现同步监视器没有锁,然后锁定并访问

补充:

  1. juc并发包:java.util.concurrent包

  2. juc并发编程会深入学习

3.死锁

  1. 某一个同步块存在两个以上的对象锁的时候,就可能会发生死锁

  2. 多个线程相互占有对方所需要的锁资源,然后形成僵持

4.Lock锁

  1. JDK 5.0 出现,显示定义同步锁,释放锁

  2. 属于juc并发包下的一个类

  3. java.util.concurrent.locks.Lock接口

  4. 使用Lock锁需要处理一个异常

  5. 与synchronized(obj){ }的区别只有一点

  6. 第一步:lock.lock(),加锁,放在try{ }中

  7. 第二步:lock.unlock(),释放锁

5、线程通信

1.线程通信分析

  1. wait():线程等待,与sleep不同,这个会释放锁;(sleep抱着锁睡觉)

  2. notify():唤醒一个处于等待状态的线程

  3. 这两个方法源于Object类

2.解决方式

生产者/消费者模型

  1. 生产者:生成产品

  2. 消费者:消费产品

  3. 生产者将生产好的产品放入缓冲区,消费者从缓冲区里面取出产品

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值