首页 > 其他分享 >多线程必知必会的知识点

多线程必知必会的知识点

时间:2022-12-24 10:03:40浏览次数:36  
标签:知识点 必知 创建 park 队列 线程 进程 volatile 多线程

说说阻塞队列的实现:可以参考ArrayBlockingQueue的底层实现(锁和同步都行);

如果队列是空的,消费者会一直等待,当生产者添加元素时候,消费者是如何知道当前队列有元素的呢?如果让你来设计阻塞队列你会如何设计,让生产者和消费者能够高效率的进行通讯呢?让我们先来看看JDK是如何实现的。

使用通知模式实现。所谓通知模式,就是当生产者往满的队列里添加元素时会阻塞住生产者,当消费者消费了一个队列中的元素后,会通知生产者当前队列可用。

通过查看JDK源码发现ArrayBlockingQueue使用了Condition来实现当我们往队列里插入一个元素时,如果队列不可用,阻塞生产者主要通过LockSupport.park(this);来实现继续进入源码,发现调用setBlocker先保存下将要阻塞的线程,然后调用unsafe.park阻塞当前线程unsafe.park是个native方法,park这个方法会阻塞当前线程,只有以下四种情况中的一种发生时,该方法才会返回。

与park对应的unpark执行或已经执行时。注意:已经执行是指unpark先执行,然后再执行的park。线程被中断时。如果参数中的time不是零,等待了指定的毫秒数时。

发生异常现象时。这些异常事先无法确定。我们继续看一下JVM是如何实现park方法的,park在不同的操作系统使用不同的方式实现,在linux下是使用的是系统方法pthread_cond_wait实现。

实现代码在JVM源码路径src/os/linux/vm/os_linux.cpp里的 os::PlatformEvent::park方法pthread_cond_wait是一个多线程的条件变量函数,cond是condition的缩写,字面意思可以理解为线程在等待一个条件发生,这个条件是一个全局变量。
这个方法接收两个参数,一个共享变量cond,一个互斥量mutex。而unpark方法在linux下是使用pthread_cond_signal实现的。park 在windows下则是使用WaitForSingleObject实现的。当队列满时,生产者往阻塞队列里插入一个元素,生产者线程会进入WAITING (parking)状态

进程通讯的方式:消息队列,共享内存,信号量,socket通讯等;

1 无名管道( pipe ):管道是一种半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系的进程间使用。进程的2亲缘关系通常是指父子进程关系。

2 高级管道(popen):将另一个程序当做一个新的进程在当前程序进程中启动,则它算是当前程序的子进程,这种方式我们成为高级管道方式。

3 有名管道 (named pipe) : 有名管道也是半双工的通信方式,但是它允许无亲缘关系进程间的通信。

4 消息队列( message queue ) : 消息队列是由消息的链表,存放在内核中并由消息队列标识符标识。消息队列克服了信号传递信息少、管道只能承载无格式字节流以及缓冲区大小受限等缺点。

5 信号量( semophore ) : 信号量是一个计数器,可以用来控制多个进程对共享资源的访问。它常作为一种锁机制,防止某进程正在访问共享资源时,其他进程也访问该资源。因此,主要作为进程间以及同一进程内不同线程之间的同步手段。

6信号 ( sinal ) : 信号是一种比较复杂的通信方式,用于通知接收进程某个事件已经发生。7共享内存( shared memory ) :共享内存就是映射一段能被其他进程所访问的内存,这段共享内存由一个进程创建,但多个进程都可以访问。

共享内存是最快的 IPC 方式,它是针对其他进程间通信方式运行效率低而专门设计的。它往往与其他通信机制,如信号两,配合使用,来实现进程间的同步和通信。8套接字( socket ) : 套解口也是一种进程间通信机制,与其他通信机制不同的是,它可用于不同机器间的进程通信

Excutors可以产生哪些线程池;

1、newCachedThreadPool:用来创建一个可缓存线程池,该线程池没有长度限制,对于新的任务,如果有空闲的线程,则使用空闲的线程执行,如果没有,则新建一个线程来执行任务。如果线程池长度超过处理需要,可灵活回收空闲线程

2、newFixedThreadPool :用来创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。定长线程池的大小通常根据系统资源进行设置:Runtime.getRuntime().availableProcessors()

3、newScheduledThreadPool:用来创建一个定长线程池,并且支持定时和周期性的执行任务

4、newSingleThreadExecutor:用来创建一个单线程化的线程池,它只用唯一的工作线程来执行任务,一次只支持一个,所有任务按照指定的顺序执行

为什么要用线程池;

在Java中,如果每当一个请求到达就创建一个新线程,开销是相当大的。在实际使用中,每个请求创建新线程的服务器在创建和销毁线程上花费的时间和消耗的系统资源,甚至可能要比花在处理实际的用户请求的时间和资源要多得多。

除了创建和销毁线程的开销之外,活动的线程也需要消耗系统资源。如果在一个JVM里创建太多的线程,可能会导致系统由于过度消耗内存或“切换过度”而导致系统资源不足。

为了防止资源不足,服务器应用程序需要一些办法来限制任何给定时刻处理的请求数目,尽可能减少创建和销毁线程的次数,特别是一些资源耗费比较大的线程的创建和销毁,尽量利用已有对象来进行服务,这就是“池化资源”技术产生的原因。

线程池主要用来解决线程生命周期开销问题和资源不足问题。通过对多个任务重用线程,线程创建的开销就被分摊到了多个任务上了,而且由于在请求到达时线程已经存在,所以消除了线程创建所带来的延迟。

这样,就可以立即为请求服务,使应用程序响应更快。另外,通过适当地调整线程池中的线程数目可以防止出现资源不足的情况

volatile关键字的用法:使多线程中的变量可见;

volatile关键字,作用是强制线程去公共堆栈中访问isContinuePrint的值。
使用volatile关键字增加了实例变量在多个线程之间的可见性,但volatile关键字有一个致命的缺陷是不支持原子性

synchronized与volatile关键字之间的比较

关键字volatile是线程同步的轻量实现,所以volatile关键字性能比synchronized好。

volatile只能修饰变量,synchronized可以修饰方法,代码块volatile不会阻塞线程,synchronized会阻塞线程volatile能保证数据的可见性,不保证原子性,synchronized可以保证原子性,可以间接保证可见性,它会将公共内存和私有内存的数据做同步处理。volatile解决的是变量在多个线程之间的可见性,

synchronized解决的是多个线程之间访问资源的同步性 请记住Java的同步机制都是围绕两点:原子性,线程之间的可见性.只有满足了这两点才能称得上是同步的。Java中的synchronized和volatile两个关键字分别执行的是原子性和线程之间的可见性

标签:知识点,必知,创建,park,队列,线程,进程,volatile,多线程
From: https://blog.51cto.com/u_15733182/5967066

相关文章

  • 省选知识点做题记录
    luogu[IOI2014]Wall砖墙题解可以转化为区间取\(min\)和区间取\(max\).规定一下下传标记的顺序推一下式子就行了.[NOIP2013提高组]华容道题解先想到了朴素的......
  • 史上最全!熬夜整理56个JavaScript高级的手写知识点!!专业扫盲!
    本文已参与「掘力星计划」,赢取创作大礼包,挑战创作激励金。前言大家好,我是林三心,基础是进阶的前提,前面我给大家分享了本菜鸟这一年来笔记中的50个JS基础知识点和50个JS高......
  • 多线程
    多线程什么是进程?什么是线程?进程是一个应用程序(1个进程是一个软件)。线程是一个进程中的执行场景/执行单元。一个进程可以启动多个线程。对于java程序来说,当在DOS命令......
  • 几个例子帮你梳理PyTorch知识点(张量、autograd)
    因为我最近想学Pytorchlightning,重构一下之前的代码,所以回来梳理一下Pytorch的语法,好进行下一步学习,所以从头重新回顾一下Pytorch。这个文章是通过几个简单例子帮大家回顾......
  • 【并发技术系列】「多线程并发编程」技术体系和并发模型的基础探究(夯实基础)
    让我们通过本篇文章一同进入并发编程技术的世界里面,相信通过这篇文文章一定会对话你的并发技术体系有一定帮助以及夯实你的基础功底。基本概念并发concurrency并行paralleli......
  • jdk 1.8 多线程
    packagecom.sleep.demo;importorg.springframework.util.CollectionUtils;importjava.util.ArrayList;importjava.util.List;importjava.util.Random;import......
  • 数据库事务的一些知识点
    在日常开发中处理好数据库事务问题是相当重要的,下面以MySQL、Spring为例整理了一些数据库事务的知识点。1.事务属性事务属性(特性、原则)是指事务ACID属性,它们分别是:原......
  • 【Linux必知必会】三剑客之sed命令详解
    sed为行编辑器,同时也是一种流编辑器,它一次处理一行内容。处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”(patternspace),接着用sed命令处理缓冲区中的内容,处理完......
  • Java多线程
    核心概念线程就是独立的执行路径在程序运行时,即使没有自己创建线程,后台也会有多个线程,如主线程,gc线程。main()称之为主线程,为系统的入口,用于执行整个程序;在一个进程......
  • 一、【Java】多线程与高并发
    一、启动多线程的三种方式1、继承Thread接口类实现run()方法staticclassMyThredextendsThread{@Overridepublicvoidrun(){system.out.println("Hellow......