栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

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

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

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、多线程概述

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

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

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

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

    线程就是独立的执行路径

    main线程,程序的入口

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

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

2、线程创建

1.线程创建的几种方式

    继承Thread类

    实现Runnable接口(重点)

    实现Callable接口(了解)

    利用Lambda表达式

    spring boot异步注解

    线程池

2.继承Thread类

Thread简介

    Thread类实现了Runnable接口

    继承了Object类

Thread类使用步骤

    继承Thread类

    重写run方法(@Override)

    调用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接口使用步骤

    定义类实现Runnable接口

    重写run方法

    执行线程需要丢入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接口

使用步骤

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

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

    创建目标对象

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

    提交执行:Future result1 = ser.submit(t1);

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

    关闭服务:ser.shutdownNow();

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

5.静态代理模式

6.Lambda表达式

3、线程状态

1.线程礼让

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

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

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

    yield():线程让步方法

2.线程强制执行

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

    可以想象成阻塞

    join():线程强制执行

3.线程状态观测

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

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

    线程运行:cpu调度后

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

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

    state方法观测线程状态

4.线程优先级

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

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

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

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

    高优先级的不一定先调度

5.守护线程

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

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

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

4、线程同步机制

1.线程同步

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

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

    解决方案

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

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

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

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

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

2.同步方法和同步块

同步方法

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

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

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

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

同步块

    synchronized(obj){ }

    obj:称为同步监视器

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

同步监视器执行过程

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

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

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

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

补充:

    juc并发包:java.util.concurrent包

    juc并发编程会深入学习

3.死锁

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

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

4.Lock锁

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

    属于juc并发包下的一个类

    java.util.concurrent.locks.Lock接口

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

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

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

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

5、线程通信

1.线程通信分析

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

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

    这两个方法源于Object类

2.解决方式

生产者/消费者模型

    生产者:生成产品

    消费者:消费产品

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

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/750001.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号