线程

Java内存模型

廉价感情. 提交于 2020-03-27 08:38:11
Java虚拟机规范中将Java运行时数据分为六种。 1.程序计数器:是一个数据结构,用于保存当前正常执行的程序的内存地址。Java虚拟机的多线程就是通过线程轮流切换并分配处理器时间来实现的,为了线程切换后能恢复到正确的位置,每条线程都需要一个独立的程序计数器,互不影响,该区域为“线程私有”。 2.Java虚拟机栈:线程私有的,与线程生命周期相同,用于存储局部变量表,操作栈,方法返回值。局部变量表放着基本数据类型,还有对象的引用。 3.本地方法栈:跟虚拟机栈很像,不过它是为虚拟机使用到的Native方法服务。 4.Java堆:所有线程共享的一块内存区域,对象实例几乎都在这分配内存。 5.方法区:各个线程共享的区域,储存虚拟机加载的类信息,常量,静态变量,编译后的代码。 6.运行时常量池:代表运行时每个class文件中的常量表。包括几种常量:编译时的数字常量、方法或者域的引用。 友情链接: Java中JVM虚拟机详解 来源: https://www.cnblogs.com/lxmyhappy/p/6761756.html

JVM内存

巧了我就是萌 提交于 2020-03-27 08:34:27
Java内存模型: Java虚拟机规范中将Java运行时数据分为六种。 1.程序计数器:是一个数据结构,用于保存当前正常执行的程序的内存地址。Java虚拟机的多线程就是通过线程轮流切换并分配处理器时间来实现的,为了线程切换后能恢复到正确的位置,每条线程都需要一个独立的程序计数器,互不影响,该区域为“线程私有”。 2.Java虚拟机栈:线程私有的,与线程生命周期相同,用于存储局部变量表,操作栈,方法返回值。局部变量表放着基本数据类型,还有对象的引用。 3.本地方法栈:跟虚拟机栈很像,不过它是为虚拟机使用到的Native方法服务。 4.Java堆:所有线程共享的一块内存区域,对象实例几乎都在这分配内存。 5.方法区:各个线程共享的区域,储存虚拟机加载的类信息,常量,静态变量,编译后的代码。 6.运行时常量池:代表运行时每个class文件中的常量表。包括几种常量:编译时的数字常量、方法或者域的引用。 来源: https://www.cnblogs.com/ng-xixi/p/9942099.html

Java面试题1

ε祈祈猫儿з 提交于 2020-03-27 07:32:16
1.抽象: 抽象就是忽略一个主题中与当前目标无关的那些方面,以便更充分地注意与当前目标有关的方面。抽象并不打算了解全部问题,而只是选择其中的一部分,暂时不用部分细节。抽象包括两个方面,一是过程抽象,二是数据抽象。 2.继承: 继承是一种联结类的层次模型,并且允许和鼓励类的重用,它提供了一种明确表述共性的方法。对象的一个新类可以从现有的类中派生,这个过程称为类继承。新类继承了原始类的特性,新类称为原始类的派生类(子类),而原始类称为新类的基类(父类)。派生类可以从它的基类那里继承方法和实例变量,并且类可以修改或增加新的方法使之更适合特殊的需要。 3.封装: 封装是把过程和数据包围起来,对数据的访问只能通过已定义的界面。面向对象计算始于这个基本概念,即现实世界可以被描绘成一系列完全自治、封装的对象,这些对象通过一个受保护的接口访问其他对象。 4. 多态性: 多态性是指允许不同类的对象对同一消息作出响应。多态性包括参数化多态性和包含多态性。多态性语言具有灵活、抽象、行为共享、代码共享的优势,很好的解决了应用程序函数同名问题。 5、String是最基本的数据类型吗? 基本数据类型包括byte、int、char、long、float、double、boolean和short。 java.lang.String类是final类型的,因此不可以继承这个类、不能修改这个类。为了提高效率节省空间

试题

牧云@^-^@ 提交于 2020-03-27 03:29:55
讲一讲并行和并发 进程的线程的区别 进程是资源分配的最小单位,线程是程序执行的最小单位。 进程有自己的独立地址空间,每启动一个进程,系统就会为它分配地址空间,建立数据表来维护代码段、堆栈段和数据段,这种操作非常昂贵。而线程是共享进程中的数据的,使用相同的地址空间,因此CPU切换一个线程的花费远比进程要小很多,同时创建一个线程的开销也比进程要小很多。 线程之间的通信更方便,同一进程下的线程共享全局变量、静态变量等数据,而进程之间的通信需要以通信的方式(IPC)进行。不过如何处理好同步与互斥是编写多线程程序的难点。 但是多进程程序更健壮,多线程程序只要有一个线程死掉,整个进程也死掉了,而一个进程死掉并不会对另外一个进程造成影响,因为进程有自己独立的地址空间。 进程间通信的有哪几种方式 管道(Pipe)及有名管道(named pipe): 信号量 共享内存 信号(Signal) 报文(Message)队列(消息队列) 套接字 线程间资源可以共享吗,进程间呢 Java并发,说一说了解哪些,volatie个synchronized的 volatile本质是告诉JVM当前变量在寄存器中的值是不确定的,需要从主存中读取。synchronized则是锁定当前变量,只有当前线程可以访问该变量,其它线程被阻塞。 volatile仅能使用在变量级别,synchronized则可以使用在变量、方法。

如何优雅地中止线程?

不羁的心 提交于 2020-03-27 01:46:14
3 月,跳不动了?>>> 本文来学习如何学习优雅地中止线程?通过 Java 线程的生老病死 的学习,我相信大家对线程的运行以及线程的状态有一定了解了,那么我们现在来学习中止线程: 错误的线程中止 - stop 首先来讲解一个错误的方式来中止线程 — stop :中止线程,并且清除监控器锁的信息,但是可能导致线程安全问题,JDK 不建议使用,类似的方法还有 destory,由于 JDK 从未实现该方法,在这里就不介绍了。 接下来通过一段程序来讲解为什么 stop 会导致线程安全问题? 首先定义一个线程类 StopThread : public class StopThread extends Thread { private int i = 0; private int j = 0; @Override public void run() { synchronized (this) { // 增加同步锁,确保线程安全 ++i; try { // 休眠10秒,模拟耗时操作 Thread.sleep(10000); } catch (InterruptedException e) { e.printStackTrace(); } ++j; } } /** * 打印 i 和 j */ public void print() { System.out.println("i=" + i + "

软件测试判断题

无人久伴 提交于 2020-03-26 23:47:28
判断题 软件测试就是为了验证软件功能实现的是否正确,是否完成既定目标的活动,所以软件测试在软件工程的后期才开始具体的工作。 (初级) ( × ) 发现错误多的模块,残留在模块中的错误也多。( √ ) (初级) 测试人员在测试过程中发现一处问题,如果问题影响不大,而自己又可以修改,应立即将此问题正确修改,以加快、提高开发的进程。( × )(初级) 单元测试通常应该先进行“人工走查”,再以白盒法为主,辅以黑盒法进行动态测试。 ( √ )(中级) 功能测试是系统测试的主要内容,检查系统的功能、性能是否与需求规格说明相同。( √ )(中级) 软件质量管理即QM由QA和QC构成,软件测试属于QC的核心工作内容。(√)(高级) 软件测试只能发现错误,但不能保证测试后的软件没有错误。(√) 软件就是程序。(X) 测试只要做到语句覆盖和分支覆盖,就可以发现程序中的所有错误。(X) I18N测试是指对产品做出具有国际性的规划,而L10N测试则是指对软件做出符合本地需求更改工作。(√)【高级】 ( × )用黑盒发测试时,测试用例是根据程序内部逻辑设计的。 ( √ )白盒测试是基于对程序控制结构了解的基础上来设计测试用例的。 ( × )测试是为了验证软件正确的实现了用户需求。 ( √ )确定测试主要测试软件功能是否满足用户的合理需求,以“需求规格说明书”为测试依据。 ( √ )软件测试时经常要输入无效的

linux查找java程序cpu占用最高的线程

不打扰是莪最后的温柔 提交于 2020-03-26 23:47:09
1. 查找进程 top查看进程占用资源情况 2.查找线程 使用top -H -p <pid>查看线程占用情况 3.查找java的堆栈信息 将线程id转换成十六进制 #printf %x 15664 #3d30 然后再使用jstack查询线程的堆栈信息 语法:jstack <pid> | grep -a 线程id(十六进制) jstack <pid> | grep -a 3d30 来源: https://www.cnblogs.com/yeyang/p/12577611.html

Java Map

拥有回忆 提交于 2020-03-26 18:55:30
Map无论在Java编程或者面试中,都占用很重要的地位,这里试图聊聊相关的概念,看看是否能够理清楚相关的思路。 HashMap HashMap 是我们经常会用到的集合类,JDK 1.7 之前底层使用了数组加链表的组合结构,如下图所示: 新添加的元素通过取模的方式,定位 Table 数组位置,然后将元素加入链表头部,这样下次提取时就可以快速被访问到。 访问数据时,也是通过取模的方式,定位数组中的位置,然后再遍历链表,依次比较,获取相应的元素。 如果 HasMap 中元素过多时,可能导致某个位置上链表很长。原本 O(1) 查找性能,可能就退化成 O(N) ,严重降低查找效率。 为了避免这种情况,当 HasMap 元素数量满足以下条件时,将会自动扩容,重新分配元素。 1// size:HashMap 中实际元素数量 2//capacity:HashMap 容量,即 Table 数组长度,默认为:16 3//loadFactor:负载因子,默认为:0.75 4 size>=capacity*loadFactor HasMap 将会把容量扩充为原来的两倍,然后将原数组元素迁移至新数组。 1void transfer(Entry[] newTable, boolean rehash) { 2 int newCapacity = newTable.length; 3 for (Entry<K,V

数据库连接池到底应该设多大?

↘锁芯ラ 提交于 2020-03-26 18:51:40
本文内容95%译自这篇文章: https://github.com/brettwooldridge/HikariCP/wiki/About-Pool-Sizing ) 我在研究HikariCP(一个数据库连接池)时无意间在HikariCP的Github wiki上看到了一篇文章(即前面给出的链接),这篇文章有力地消除了我一直以来的疑虑,看完之后感觉神清气爽。故在此做译文分享。 接下来是正文 数据库连接池的配置是开发者们常常搞出坑的地方,在配置数据库连接池时,有几个可以说是和直觉背道而驰的原则需要明确。 1万并发用户访问 想象你有一个网站,压力虽然还没到Facebook那个级别,但也有个1万上下的并发访问——也就是说差不多2万左右的TPS。那么这个网站的数据库连接池应该设置成多大呢?结果可能会让你惊讶,因为这个问题的正确问法是: “这个网站的数据库连接池应该设置成多 小 呢?” 下面这个视频是Oracle Real World Performance Group发布的,请先看完: http://www.dailymotion.com/video/x2s8uec (因为这视频是英文解说且没有字幕,我替大家做一下简单的概括:) 视频中对Oracle数据库进行压力测试,9600并发线程进行数据库操作,每两次访问数据库的操作之间sleep 550ms,一开始设置的中间件线程池大小为2048:

自旋锁、排队自旋锁、MCS锁、CLH锁

十年热恋 提交于 2020-03-26 11:30:14
3 月,跳不动了?>>> 自旋锁(Spin lock) 自旋锁是指当一个线程尝试获取某个锁时,如果该锁已被其他线程占用,就一直循环检测锁是否被释放,而不是进入线程挂起或睡眠状态。 自旋锁适用于锁保护的临界区很小的情况,临界区很小的话,锁占用的时间就很短。 简单的实现 import java.util.concurrent.atomic.AtomicReference; public class SpinLock { private AtomicReference<Thread> owner = new AtomicReference<Thread>(); public void lock() { Thread currentThread = Thread.currentThread(); // 如果锁未被占用,则设置当前线程为锁的拥有者 while (owner.compareAndSet(null, currentThread)) { } } public void unlock() { Thread currentThread = Thread.currentThread(); // 只有锁的拥有者才能释放锁 owner.compareAndSet(currentThread, null); } } SimpleSpinLock里有一个owner属性持有锁当前拥有者的线程的引用