IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> JUC知识点 -> 正文阅读

[Java知识库]JUC知识点

一.线程中断标记

1.interrupt

实例方法interrupt()仅仅是设置线程的中断状态为true,不会停止线程

1.如果线程处于正常活动状态,那么会将该线程的中断标志设置为 true。
被设置中断标志的线程将继续正常运行,不受影响。所以,interrupt()并不能真正的中断线程,需要被调用的线程自己进行配合才行。

2.如果线程处于被阻塞状态(例如处于sleep, wait,join等状态),在别的线程中调用当前线程对象的interrupt方法,那么线程将立即退出被阻塞状态,并抛出一个InterruptedException异常。并且会将中断状态置为false,需要重新将标志为置为true

public static void m5()
    {
        Thread t1 = new Thread(() -> {
            while (true) {
                if (Thread.currentThread().isInterrupted()) {
                    System.out.println("-----isInterrupted() = true,程序结束。");
                    break;
                }
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();//???????  //线程的中断标志位为false,无法停下,需要再次掉interrupt()设置true
                    e.printStackTrace();
                }
                System.out.println("------hello Interrupt");
            }
        }, "t1");
        t1.start();

        try { TimeUnit.SECONDS.sleep(3); } catch (InterruptedException e) { e.printStackTrace(); }

        new Thread(() -> {
            t1.interrupt();//修改t1线程的中断标志位为true
        },"t2").start();
    }

2.interrupted

判断线程是否被中断,并清除当前中断状态这个方法做了两件事:
1返回当前线程的中断状态
2将当前线程的中断状态设为false

3.isInterrupted

判断当前线程是否被中断(通过检查中断标志位)

二.LockSupport

1.1 LockSupport.unpark();

会给指定线程发通行证,一个线程只能发一次,如果要发多个需要开多个线程去unpark();

1.2LockSupport.park();

线程加锁,可以锁多次,锁几次就得解几次,但是不能提前解多次,只能解一次

提前发了两次通行证,但只有一个生效,线程无法终止

public static void main(String[] args) {

        Thread thread = new Thread(() -> {

            try {
                Thread.sleep(2000);
                System.out.println("t1开始运行---");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            LockSupport.park();
            LockSupport.park();
        });
        thread.start();
        new Thread(() ->{
            System.out.println("开始解锁11111");
            LockSupport.unpark(thread);
        }).start();

        new Thread(() ->{
            System.out.println("开始解锁22222");
            LockSupport.unpark(thread);
        }).start();

    }

先上锁多次再多次解锁可以成功,但是如果出现同时解锁会导致线程一直运行

public static void main(String[] args) {

        Thread thread = new Thread(() -> {

            try {
                //Thread.sleep(2000);
                System.out.println("t1开始运行---");
            } catch (Exception e) {
                e.printStackTrace();
            }
            LockSupport.park();
            LockSupport.park();
        });
        thread.start();
        new Thread(() ->{
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("开始解锁11111");
            LockSupport.unpark(thread);
        }).start();

        new Thread(() ->{
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("开始解锁22222");
            LockSupport.unpark(thread);
        }).start();

    }

三、JMM

在这里插入图片描述

1、JMM定义


Java虚拟机规范中试图定义一种Java内存模型《java Memory Model,简称JMM)来屏蔽掉各种硬件和操作系统的内存访问差异以实现让Java程序在各种平台下都能达到一致的内存访问效果。

JMM(Java内存模型Java Memory Model,简称JMM)本身是一种抽象的概念1不真实存在它仅仅描述的是一组约定或规范,通过这组规范定义了程序中(尤其是多线程)各个变量的读写访问方式并决定一个线程对共享变量的写入何时以及如何变成对另一个线程可见,关键技术点都是围绕多线程的原子性、可见性和有序性展开的。

作用:
1通过JMM来实现线程和主内存之间的抽象关系。
2屏蔽各个硬件平台和操作系统的内存访问差异以实现让Java程序在各种平台下都能达到一致的内存访问效果。

2.JMM三大特性

2.1 可见性

是指当一个线程修改了某一个共享变量的值,其他线程是否能够立即知道该变更,JMM规定了所有的变量都存储在主内存中。

在这里插入图片描述
2.2有序性

对于一个线程的执行代码而言,我们总是习惯性认为代码的执行总是从上到下,有序执行。但为了提供性能,编译器和处理器通常会对指令序列进行重新排序。
指令重排可以保证串行语义一致,但没有义务保证多线程间的语义也一致,即可能产生"脏读",简单说,
两行以上还相干的代码在执行的时候有可能先执行的不是第一条,不见得是从上到下顺序执行,执行顺序会被优化。


单线程环境里面确保程序最终执行结果和代码顺序执行的结果一致。处理器在进行重排序时必须要考虑指令之间的数据依赖性
多线程环境中线程交替执行,由于编译器优化重排的存在,两个线程中使用的变量能否保证一致性是无法确定的,结果无法预测

在这里插入图片描述

2.3

指一个操作是不可中断的,即多线程环境下,操作不能被其他线程干扰

3.JVM读取过程

由于JVM运行程序的实体是线程,而每个线程创建时JVM都会为其创建一个工作内存(有些地方称为栈空间),
工作内存是每个线程的私有数据区域,而Java内存模型中规定所有变量都存储在主内存,主内存是共享内存区域,
所有线程都可以访问,但线程对变量的操作(读取赋值等)必须在工作内存中进行,
首先要将变量从主内存拷贝到的线程自己的工作内存空间,然后对变量进行操作,
操作完成后再将变量写回主内存,不能直接操作主内存中的变量,各个线程中的工作内存中存储着主内存中的变量副本拷贝,
因此不同的线程间无法访问对方的工作内存,线程间的通信(传值)必须通过主内存来完成。:

线程和主内存之间的关系

1线程之间的共享变量存储在主内存中(从硬件角度来说就是内存条)
2每个线程都有一个私有的本地工作内存,本地工作内存中存储了该线程用来读I写共享变量的副本(从硬件角度来说就是CPU的缓存,比如寄存器、L1、L2、L3缓存等)

在这里插入图片描述

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2021-12-10 10:55:44  更:2021-12-10 10:56:42 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 6:36:34-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码