本地线程

Java并发多线程面试题 Top 50

吃可爱长大的小学妹 提交于 2019-12-06 14:36:22
不管你是新程序员还是老手,你一定在面试中遇到过有关线程的问题。Java语言一个重要的特点就是内置了对并发的支持,让Java大受企业和程序员的欢迎。大多数待遇丰厚的Java开发职位都要求开发者精通多线程技术并且有丰富的Java程序开发、调试、优化经验,所以线程相关的问题在面试中经常会被提到。 在典型的Java面试中, 面试官会从线程的基本概念问起, 如:为什么你需要使用线程, 如何创建线程,用什么方式创建线程比较好(比如: 继承thread类还是调用Runnable接口 ),然后逐渐问到并发问题像在Java并发编程的过程中遇到了什么挑战,Java内存模型,JDK1.5引入了哪些更高阶的并发工具,并发编程常用的 设计模式 ,经典多线程问题如生产者消费者,哲学家就餐,读写器或者简单的有界缓冲区问题。仅仅知道线程的基本概念是远远不够的, 你必须知道如何处理 死锁 , 竞态条件 ,内存冲突和线程安全等并发问题。掌握了这些技巧,你就可以轻松应对多线程和并发面试了。 许多Java程序员在面试前才会去看面试题,这很正常。因为收集面试题和练习很花时间,所以我从许多面试者那里收集了Java多线程和并发相关的50个热门问题。我只收集了比较新的面试题且没有提供全部答案。想必聪明的你对这些问题早就心中有数了, 如果遇到不懂的问题,你可以用Google找到答案。若你实在找不到答案,可以在文章的评论中向我求助

初识JVM

匆匆过客 提交于 2019-12-06 13:54:12
   一、程序计数器    记住下一条jvm指令的执行地址,解释器会去程序计数器拿jvm指令。  线程私有的,CPU会给每个线程分配时间片,时间片执行完会切换线程。    唯一不会出现内存溢出的区域。 二、虚拟机栈    线程运行需要的内存空间,每个线程都有一个栈。    由多个栈帧组成,每个方法运行需要的内存(参数、局部变量、返回值),先入后出。    每个线程只能有一个活动栈帧,就是正在执行的方法。    垃圾回收不涉及栈内存。    栈内存参数:-Xss 1024k。栈内存变大,总线程就会变少。    方法内的局部变量如果没有逃离方法的作用范围,则是线程安全的。    栈内存溢出错误:StackOverflowError     案例:     (一)CPU占用过高        1、查看所有进程的cpu占用率,获取哪个进程占用cpu最高:top。       2、查看某个进程的哪个线程占用cpu最高:ps H -eo pid,tid,%cpu | grep ${pid}。       3、查看某个进程的所有线程详细信息:jstack ${pid}。 三、本地方法栈    本地方法运行使用的内存,例如object.clone(),被native修饰的。 四、堆(heap)    通过new创建的对象都会放在堆中,线程共享的,有垃圾回收机制。    内存溢出异常:java

JVM内运行时数据区

拥有回忆 提交于 2019-12-06 12:54:14
JVM的基本区域:    类加载子系统        运行时数据区(内存区域)        执行引擎      运行时数据区域          方法区(Method Area)     类的所有字和方法字节码,以及一些特殊方法如构造函数,接口代码也在这里定义。简单来说,所有定义的方法的信息都保存在该区域,静态变量+常量+类信息(构造方法/接口定义)+运行时常量池都存在方法区中,虽然java虚拟机规范把方法区描述为堆的一个逻辑部分,但是它却有一个别名叫做Non+Heap(堆),目的应该是为了和java的堆区分开;   堆(Heap)     虚拟机启动时自动分配创建,用于存放对象的实例,几乎所有对象在堆上分配内存,当对象无法在该空间申请到内存是将抛出OutOfMemoryError异常。同时也是垃圾收集器管理的主要区域;             新生代           类出生,成长,消亡的区域,一个类在这里产生,应用,最后被垃圾回收器收集,结束生命。         新生代分为两部分:伊甸区(Eden space)和幸存者(Survivor space),所有的类都是在伊甸区被new出来的。辛存区又分为From和To区。当Eden区的空间用完时,程序又需要创建对象,JVM的垃圾回收器将Eden区进行垃圾回收(Minor GC),将Eden区中的不再被对象应用的对象进行销毁

5.3.6 程序计数器

谁说我不能喝 提交于 2019-12-06 10:55:39
对于一个运行中的Java程序而言,其中的每一个线程都有它自己的PC (程序计数器)寄存 器,它是在该线程启动时创建的。PC寄存器的大小是一个字长,因此它既能够持有一个本地指 针,也能够持有一个returnAddress。当线程执行某个Java方法时,PC寄存器的内容总是下一条 将被执行指令的“地址“,这里的“地址”可以是一个本地指针,也可以是在方法字节码中相对 于该方法起始指令的偏移量。如果该线稈正在执行一个本地方法,那么此时PC寄存器的值是 “undefined”。 来源: https://www.cnblogs.com/mongotea/p/11979462.html

全面理解Java内存模型

不羁岁月 提交于 2019-12-06 10:44:53
------------恢复内容开始------------ 1. java内存模型即java Memory Model,简称JMM.JMM定义了Java虚拟机(JVM)在计算机内存(RAM)中的工作方式。JVM是整个计算机虚拟模型,所以JMM是隶属于JVM的。 2.并发编程有两个关键问题: 线程之间的通信和同步 。 3.线程之间的 通信 机制有两种: 共享内存和消息传递 。 1)在 共享内存 的并发模型里,线程之间共享程序的公共状态,线程之间通过写读内存中的公共状态来 隐式 进行通信,典型的共享内存通信方式就是通过共享对象进行通信。 2)在 消息传递 的并发模型里,线程之间没有公共状态,线程之间必须通过明确的发送消息来 显式 进行通信,在Java中典型的消息传递方式是wait()和notify() 4.线程之间的 同步 是指程序用于控制不同线程之间操作发生相对顺序的机制。 1)在 共享内存 并发模型里,同步是 显式 进行的。必须显式指定某个方法或某段代码需要在线程之间互斥执行。 2)在 消息传递 的并发模型里,由于消息的发送必须在消息的接收之前,因此同步是 隐式 进行的。 5.Java的并发采用的是 共享内存模型 ,即Java内存模型(简称JMM), JMM决定一个线程对共享变量的写入合适对另一个线程可见 。从抽象的角度来看, JMM定义了线程和主内存之间的抽象关系

threadlocal原理分析

寵の児 提交于 2019-12-06 09:37:07
简介 早在JDK 1.2的版本中就提供java.lang.ThreadLocal,ThreadLocal为解决多线程程序的并发问题提供了一种新的思路。使用这个工具类可以很简洁地编写出优美的多线程程序。当使用ThreadLocal维护变量时,ThreadLocal为每个使用该变量的线程提供独立的变量副本,所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本。从线程的角度看,目标变量就象是线程的本地变量,这也是类名中“Local”所要表达的意思。所以,在Java中编写线程局部变量的代码相对来说要笨拙一些,因此造成线程局部变量没有在Java开发者中得到很好的普及。引自@ 枫之逆 人们常说,锁是一种以时间换空间的机制,而ThreadLocal正好是以空间换时间的。 和锁的比较 为什么要先强调这一点,因为从简介上看,容易使人们联想到ThreadLocal似乎是一种解决Java多线程环境中线程同步与线程安全方法,其实不然,这里要设计到两个概念:线程安全,线程同步,事实上,ThreadLocal只解决线程安全的问题,并不能解决线程同步的问题,这也造成在刚学习的时候,我总是在苦想,ThreadLocal既然为每个线程拷贝一份变量,那怎么再进行同步呢?查了很多资料后才想明白,ThreadLocal并不是用来解决线程同步的,所以它与锁可以说是没有什么关系的,彼此各有所长,不能代替

python线程障碍对象Barrier(34)

笑着哭i 提交于 2019-12-06 06:26:37
python线程Barrier俗称障碍对象,也称栅栏,也叫屏障。 一.线程障碍对象Barrier简介 # 导入线程模块 import threading # 障碍对象barrier barrier = threading.Barrier(parties, action=None, timeout=None) parties — 线程计数器,记录线程数量,也称线程障碍数量; action — 是一个可调用函数,当等待的线程到达了线程障碍数量parties,其中一个线程会首先调用action 对应函数,之后再执行线程自己内部的代码; timeout — 默认的超时时间; 二.线程障碍对象Barrier原理 与之前介绍 互斥锁Lock/事件Event/定时器Timer等不同,多线程Barrier会设置一个线程障碍数量parties,如果等待的线程数量没有达到障碍数量parties,所有线程会处于阻塞状态,当等待的线程到达了这个数量就会唤醒所有的等待线程。 可能说的有点抽象,以播放器为例子:首先一个线程做播放器初始化工作(加载本地文件或者获取播放地址),然后一个线程获取视频画面,一个线程获取视频声音,只有当初始化工作完毕,视频画面获取完毕,视频声音获取完毕,播放器才会开始播放,其中任意一个线程没有完成,播放器会处于阻塞状态直到三个任务都完成! 三.多线程障碍对象Barrier相关函数介绍

Java内存模型原理

妖精的绣舞 提交于 2019-12-06 00:51:39
这篇文章主要介绍模型产生的问题背景,解决的问题,处理思路,相关实现规则,环环相扣,希望读者看完这篇文章后能对 Java 内存模型体系产生一个相对清晰的理解,知其然知其所以然。 内存模型产生背景 在介绍 Java 内存模型之前,我们先了解一下物理计算机中的并发问题,理解这些问题可以搞清楚内存模型产生的背景。 物理机遇到的并发问题与虚拟机中的情况有不少相似之处,物理机的解决方案对虚拟机的实现有相当的参考意义。 物理机的并发问题 硬件的效率问题 计算机处理器处理绝大多数运行任务都不可能只靠处理器“计算”就能完成,处理器至少需要与内存交互,如读取运算数据、存储运算结果,这个 I/O 操作很难消除(无法仅靠寄存器完成所有运算任务)。 由于计算机的存储设备与处理器的运算速度有几个数量级的差距,为了避免处理器等待缓慢的内存完成读写操作,现代计算机系统通过加入一层读写速度尽可能接近处理器运算速度的高速缓存。 缓存作为内存和处理器之间的缓冲: 将运算需要使用到的数据复制到缓存中,让运算能快速运行,当运算结束后再从缓存同步回内存之中。 缓存一致性问题 基于高速缓存的存储系统交互很好的解决了处理器与内存速度的矛盾,但是也为计算机系统带来更高的复杂度,因为引入了一个新问题:缓存一致性。 在多处理器的系统中(或者单处理器多核的系统),每个处理器(每个核)都有自己的高速缓存,而它们有共享同一主内存(Main

Jmeter进行文件下载

别来无恙 提交于 2019-12-06 00:07:58
Jmeter利用beanshell实现文件下载 下载图片 下载文件,就是把某个文件保存到本地。就以这个图片为例:https://xiaochengxu-t.daydaycook.com.cn/701321547290907 请求方式(因为是获取数据,所以是get请求)、写好下载的地址,由于要把文件保存到咱们本地的,jmeter没有现成的东西可以用,需要写beanshell来实现,把文件保存到本地,具体步骤如下: 1、添加线程组 (右击 测试计划-添加-Threads(Users)-线程组) 2、添加一个http请求(右击 线程组-添加-Sampler-HTTP请求) 3、填写Http请求中的url和路径 4、添加BeanShell Sampler(右击 线程组-添加-Sampler-BeanShell Sampler) 5、编写BeanShell Sample 代码如下: import java.io.*; byte[] result = prev.getResponseData(); //这个是获取到请求返回的数据,prev是获取上个请求的返回 String file_name = "/Users/ddc-test/Downloads/baidu.jpg"; //代表存放文件的位置和文件名, 相对路径的话会保存到bin 目录下,且保存的文件名的后缀与原图一致 File file

synchronized原理

一个人想着一个人 提交于 2019-12-05 20:59:39
一、概念 是利用锁的机制来实现同步的。 锁机制有如下两种特性: 互斥性: 即在同一时间只允许一个线程持有某个对象锁,通过这种特性来实现多线程中的协调机制,这样在同一时间只有一个线程对需同步的代码块(复合操作)进行访问。互斥性我们也往往称为操作的原子性。 可见性: 必须确保在锁被释放之前,对共享变量所做的修改,对于随后获得该锁的另一个线程是可见的(即在获得锁时应获得最新共享变量的值),否则另一个线程可能是在本地缓存的某个副本上继续操作从而引起不一致。 二、synchronized的用法 根据修饰对象分类 1、 同步方法 (1) 同步非静态方法 Public synchronized void methodName(){ …… } (2) 同步静态方法 Public synchronized static void methodName(){ …… } 2、同步代码块   synchronized(this|object) {}   synchronized( 类.class) {}   Private final Object MUTEX =new Object();   Public void methodName(){    Synchronized (MUTEX ){   ……   }   } 根据获取的锁分类 1、获取对象锁   synchronized(this