Java
Java基础&集合&多线程虚拟机等
z止于至善
这个作者很懒,什么都没留下…
展开
-
JVM内存分配策略--内存分配
Java技术体系中的自动内存管理解决了两个问题:给对象分配内存以及回收分配给对象的内存。关于回收内存,之前的文章提到了对象已死吗(对象存活判定算法、回收方法区)和垃圾收集算法。对象的内存分配,往大方向讲,就是在堆上分配(但也可能经过JIT编译后被拆散为标量类型并间接地栈上分配),对象主要分配在新生代的Eden区上,如果启动了本地线程分配缓存,将按线程优先在TLAB上分配。少数情况有可能会直...原创 2018-08-24 09:53:33 · 215 阅读 · 0 评论 -
Java虚拟机之内存区域--HotSpot虚拟机对象
HotSpot虚拟机在Java堆中对象分配、布局和访问。1.对象的创建在语言层面上,创建对象(例如克隆、反序列化)通常仅仅是一个new关键字而已。虚拟机遇到一条new指令时,首先将去检查这个指令的参数是否能在常量池中定位到一个类的符号引用,并且检查这个符号引用代表的类是否已被加载、解析和初始化过。如果没有,那必须先执行相应的类加载过程。在类加载检查通过后,接下来虚拟机将为新生对象分...原创 2018-08-20 22:49:32 · 263 阅读 · 0 评论 -
Java虚拟机之内存溢出异常--OutOfMemoryError异常
针对HotSpot虚拟机1.Java堆溢出Java堆用于存储对象实例,只要不断地创建对象,并且保证GC Roots到对象之间有可达路径来避免垃圾回收机制清除这些对象,那么在对象数量到达最大堆的容量限制后就会产生内存溢出异常。与内存相关的虚拟机参数:-Xms:堆的最小值-Xmx:堆的最大值将-Xms参数和-Xmx参数设置为一样,即可避免堆自动扩展。通过参数-XX:+Hea...原创 2018-08-21 16:14:21 · 395 阅读 · 0 评论 -
JVM类加载机制--类加载过程
包含了加载、验证、准备、解析和初始化这 5 个阶段。1. 加载“加载”是“类加载”(Class Loading)过程的一个阶段,注意不要混淆。在加载阶段,虚拟机需要完成以下三件事:通过一个类的全限定名来获取定义此类的二进制字节流。 将这个字节流所代表的静态存储结构转化为方法区的运行时存储结构。 在内存中生成一个代表这个类的 java.lang.Class 对象,作为方法区这个类...原创 2018-10-13 10:27:50 · 129 阅读 · 0 评论 -
JVM类加载机制--概述&时机&初始化
概述虚拟机的类加载机制:虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验、转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型。类是在运行期间第一次使用时动态加载的,而不是编译时期一次性加载。因为如果在编译时期一次性加载,那么会占用很多的内存。在Java语言里,类型的加载、连接和初始化过程都是在程序运行期间完成的,这种策略虽然会使类加载时稍微增加一些性能开销...原创 2018-08-24 10:36:08 · 255 阅读 · 0 评论 -
JVM垃圾收集器--对象已死吗(对象存活判定算法)
在堆里面存放着Java世界中几乎所有的对象实例,垃圾收集器在对堆进行回收前,第一件事情就是要确定这些对象之中哪些还“存活”者,哪些已经“死去”(即不可能再被任何途径使用的对象)。1.引用记数法基本思路:给对象中添加一个引用计数器,每当有一个地方引用它时,计数器值就加1;当引用失效时,计数器值就减1;任何时刻计数器为0的对象就是不可能再被使用的。实现简单,判定效率高,大部分情况下是一个不...原创 2018-08-22 10:26:13 · 199 阅读 · 0 评论 -
JVM垃圾收集器--回收方法区
方法区的概念在前面的文章中已经讲到,点击查看一般会认为方法区(或者HotSpot虚拟机中的永久代)是没有垃圾收集的,Java虚拟机规范中确实说过可以不要求虚拟机在方法区实现垃圾收集,而且在方法区中进行垃圾收集的“性价比”一般比较低:在堆中,尤其是在新生代中,常规应用进行一次垃圾收集一般可以回收70%~95%的空间,而永久代的垃圾收集效率远低于此。永久代的垃圾收集主要回收两部分内容:废弃常量...原创 2018-08-23 15:59:31 · 651 阅读 · 0 评论 -
JVM垃圾收集器--垃圾收集算法
标记-清除算法最基础的收集算法,包括”标记“和”清除“两个阶段。基本思路:首先标记出所有需要回收的对象,在标记完成后统一回收所有被标记的对象。”标记-清除“算法示意图不足:效率问题,标记和清除两个过程的效率都不高。 空间问题,标记清除之后会产生大量的不连续的碎片,空间碎片太多可能会导致以后在程序运行过程中需要分配较大对象时,无法找到足够的连续内存而不得不提前触发另一次垃圾收集...原创 2018-08-23 16:48:24 · 259 阅读 · 0 评论 -
Java虚拟机之内存区域--运行时数据区域
Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域,包括以下几个运行时数据区域。Java虚拟机运行时数据区1.程序计数器是一块较小的内存空间,它可以看作是当前线程所执行的字节码的行号指示器。如果线程正在执行的是一个Java方法,这个计数器记录的是正在执行的虚拟机字节码指令的地址;如果正在执行的是Native方法,这个计数器值则为空(Undefined)...原创 2018-08-20 21:33:48 · 327 阅读 · 0 评论 -
出场率比较高的一道多线程安全面试题
Reference:https://www.javastack.cn/article/2018/thread-security-list-question/ ArrayList 是线程不安全的,要使用线程安全的就使用 Vector,这也是各种 Java 面试宝典里面所提及的,可能很多工作好几年的程序员都停留在这个知识面上。先说说为什么 ArrayList 是线程不安全的吧,来看以下的代码。...转载 2019-02-05 09:39:18 · 290 阅读 · 0 评论 -
Java线程同步机制--Synchronized关键字
Java平台中的任何一个对象都有唯一一个与之关联的锁。这种锁被称为监视器(Monitor)或者内部锁(Intrinsic Lock)。内部锁是一种排他锁,它能够保障原子性、可见性和有序性。内部锁是通过synchronized关键字实现的。synchronized关键字可以修饰方法以及代码块(花括号“{}”包裹的代码)。synchronized关键字修饰的方法被称为同步方法(Synchron...原创 2018-12-25 19:19:28 · 437 阅读 · 0 评论 -
Java并发--互斥同步--synchronized和ReentrantLock比较
比较1. 锁的实现synchronized 是 JVM 实现的,而 ReentrantLock 是 JDK 实现的。2. 性能新版本 Java 对 synchronized 进行了很多优化,例如自旋锁等,synchronized 与 ReentrantLock 大致相同。3. 等待可中断当持有锁的线程长期不释放锁的时候,正在等待的线程可以选择放弃等待,改为处理其他事情。...原创 2018-09-13 11:12:44 · 662 阅读 · 0 评论 -
volatile和synchronized区别&乐观锁、悲观锁
volatile和synchronized区别volatile是变量修饰符,其修饰的变量具有可见性,Java的做法是将该变量的操作放在寄存器或者CPU缓存上进行,之后才会同步到主存,使用volatile修饰符的变量是直接读写主存,volatile不保证原子性,同时volatile禁止指令重排。 synchronized作用于一段代码或者方法,保证可见性,又保证原子性,可见性是synchron...原创 2018-09-13 22:26:22 · 2297 阅读 · 0 评论 -
多线程编程 sleep() 和 wait() 的5个区别
原文:https://blog.csdn.net/youanyyou/article/details/82766976sleep(休眠) 和 wait(等待) 方法是 Java 多线程中常用的两个方法。1 使用限制使用 sleep 方法可以让让当前线程休眠,时间一到当前线程继续往下执行,在任何地方都能使用,但需要捕获 InterruptedException 异常。try { ...转载 2018-12-05 10:51:21 · 343 阅读 · 0 评论 -
秒杀系统必须考虑的 3 个技术问题
Reference:秒杀系统必须考虑的 3 个技术问题1、并发队列的选择Java的并发包提供了三个常用的并发队列实现,分别是:ArrayBlockingQueue、ConcurrentLinkedQueue 和 LinkedBlockingQueue 。ArrayBlockingQueue是初始容量固定的阻塞队列,我们可以用来作为数据库模块成功竞拍的队列,比如有10个商品,那么我们就设...转载 2019-02-25 20:43:49 · 242 阅读 · 0 评论 -
Java并发--互斥同步--Java两种锁机制synchronized和ReentrantLock详解
Java 提供了两种锁机制来控制多个线程对共享资源的互斥访问,第一个是 JVM 实现的 synchronized,而另一个是 JDK 实现的 ReentrantLock。synchronized1. 同步一个代码块public void func() { synchronized (this) { // ... }}它只作用于同一个对象,如果调用...原创 2018-10-11 13:03:16 · 572 阅读 · 0 评论 -
Java并发--线程之间的协作
当多个线程可以一起工作去解决某个问题时,如果某些部分必须在其它部分之前完成,那么就需要对线程进行协调。join()在线程中调用另一个线程的 join() 方法,会将当前线程挂起,而不是忙等待,直到目标线程结束。对于以下代码,虽然 b 线程先启动,但是因为在 b 线程中调用了 a 线程的 join() 方法,b 线程会等待 a 线程结束才继续执行,因此最后能够保证 a 线程的输出先于 b...原创 2018-10-12 20:27:36 · 345 阅读 · 0 评论 -
Java多线程--使用线程的三种方法详解
有三种使用线程的方法:实现 Runnable 接口; 实现 Callable 接口; 继承 Thread 类。实现 Runnable 和 Callable 接口的类只能当做一个可以在线程中运行的任务,不是真正意义上的线程,因此最后还需要通过 Thread 来调用。可以说任务是通过线程驱动从而执行的。实现 Runnable 接口需要实现 run() 方法。通过 Thread 调...原创 2018-10-11 12:32:13 · 201 阅读 · 0 评论 -
多线程通信的三大法器--wait, notify, notifyAll
原文:https://blog.csdn.net/youanyyou/article/details/84560604wait, notify, notifyAll 是多线程之间通信最重要的 3 个方法。1 定义wait:让持有该对象锁的线程等待;notify: 唤醒任何一个持有该对象锁的线程;notify: 唤醒所有持有该对象锁的线程;它们 3 个的关系是,调用对象的 w...转载 2018-12-05 11:00:34 · 248 阅读 · 0 评论 -
Java并发--基础线程机制&中断
基础线程机制1.ExecutorExecutor 管理多个异步任务的执行,而无需程序员显式地管理线程的生命周期。这里的异步是指多个任务的执行互不干扰,不需要进行同步操作。主要有三种 Executor:CachedThreadPool:一个任务创建一个线程; FixedThreadPool:所有任务只能使用固定大小的线程; SingleThreadExecutor:相当于大小为 ...原创 2018-10-12 20:21:54 · 224 阅读 · 0 评论 -
Java容器--概览以及比较
容器主要包括 Collection 和 Map 两种,Collection 存储着对象的集合,而 Map 存储着键值对(两个对象)的映射表。Collection1. Set TreeSet:基于红黑树实现,支持有序性操作,例如根据一个范围查找元素的操作。但是查找效率不如 HashSet,HashSet 查找的时间复杂度为 O(1),TreeSet 则为 O(logN)。 H...原创 2018-10-16 10:54:05 · 524 阅读 · 0 评论 -
散列表(HashMap)的实现
HashMap 概述HashMap 是基于哈希表的 Map 接口的非同步实现。此实现提供所有可选的映射操作,并允许使用 null 值和 null 键。此类不保证映射的顺序,特别是它不保证该顺序恒久不变。此实现假定哈希函数将元素适当地分布在各桶之间,可为基本操作(get 和 put)提供稳定的性能。迭代 collection 视图所需的时间与 HashMap 实例的“容量”(桶的数量)及...原创 2018-08-28 16:57:50 · 988 阅读 · 0 评论 -
变长数组(ArrayList)的实现
实现变长数组所需要的方法:初始化数组、添加元素、获取指定位置的元素、设置指定位置的元素、获取数组的长度、是否为空。使用泛型实现。扩展方法:是否包含指定元素、返回指定元素的下标(如果不存在,返回-1;如果存在,返回第一个找到的元素)、返回最后一个元素。返回下标是通过遍历数组做到的,而是否包含元素也可以通过返回指定元素的下标这种方法实现。实现了返回最后一个元素、返回第一个元素和清空数组...原创 2018-08-28 16:11:10 · 1478 阅读 · 0 评论 -
Hashtable 与 HashMap 的6个区别
Hashtable 基于 Dictionary 类,而 HashMap 是基于 AbstractMap。Dictionary 是任何可将键映射到相应值的类的抽象父类,而 AbstractMap 是基于 Map 接口的实现,它以最大限度地减少实现此接口所需的工作。 HashMap 的 key 和 value 都允许为 null,而 Hashtable 的 key 和 value 都不允许为 nul...转载 2018-09-13 09:58:05 · 174 阅读 · 0 评论 -
Java 中初始化 List 集合的 6 种方式
原文:https://blog.csdn.net/youanyyou/article/details/84846486List 是 Java 开发中经常会使用的集合,你们知道有哪些方式可以初始化一个 List 吗?这其中不缺乏一些坑,今天栈长我给大家一一普及一下。1 常规方式List<String> languages = new ArrayList<>();...转载 2018-12-07 20:34:53 · 239 阅读 · 0 评论 -
再谈HashMap
回顾:散列表(HashMap)概述&数据结构&实现存储结构JDK7 中的 HashMap 采用大家所熟悉的数组+链表的结构来存储数据。JDK8 中的 HashMap 采用了数组+链表或树的结构来存储数据。重要参数HashMap中有两个重要的参数,容量(Capacity) 和 负载因子(Load factor)Initial capacity 决定 bucke...原创 2018-09-14 09:35:09 · 162 阅读 · 0 评论 -
散列表(HashMap)概述&数据结构&实现
HashMap 概述HashMap 是基于哈希表的 Map 接口的非同步实现。此实现提供所有可选的映射操作,并允许使用 null 值和 null 键。此类不保证映射的顺序,特别是它不保证该顺序恒久不变。此实现假定哈希函数将元素适当地分布在各桶之间,可为基本操作(get 和 put)提供稳定的性能。迭代 collection 视图所需的时间与 HashMap 实例的“容量”(桶的数量)及其大...原创 2018-09-13 09:51:26 · 222 阅读 · 0 评论 -
Java基础笔记整理5--JVM&NullPointerException&类方法&实例方法&finally语句块
1.下列关于管道(Pipe)通信的叙述中,正确的是(A)A.进程对管道进行读操作和写操作都可能被阻塞B.一个管道只能有一个进程或一个写进程对其操作C.一个管道可实现双向数据传输D.管道的容量仅受磁盘容量大小限制笔记:A.正确,因为管道为空,读操作会被阻塞;管道满了,写操作会被阻塞B.可以有多个进程对其读;也可以有多个进程写,只不过不能同时写。并且题目没有说“同时”...原创 2018-07-01 14:29:50 · 229 阅读 · 0 评论 -
Java基础笔记整理1--多线程&集合Collection
1. 下列说法正确的是(B D)A 我们直接调用Thread对象的run方法会报异常,所以我们应该使用start方法来开启一个线程B 一个进程是一个独立的运行环境,可以被看做一个程序或者一个应用。而线程是在进程中执行的一个任务。Java运行环境是一个包含了不同的类和程序的单一进程。线程可以被称为轻量级进程。线程需要较少的资源来创建和驻留在进程中,并且可以共享进程中的资源C syn...原创 2018-06-28 18:55:48 · 452 阅读 · 0 评论 -
Java基础笔记整理7--反射&threadlocal
1.JAVA反射机制主要提供了以下哪些功能 (A B C D)在运行时判断一个对象所属的类在运行时构造一个类的对象在运行时判断一个类所具有的成员变量和方法在运行时调用一个对象的方法2.下面有关java threadlocal说法正确的有 (A B C D)ThreadLocal存放的值是线程封闭,线程间互斥的,主要用于线程内共享一些数据,避免通过参数来传递线...原创 2018-07-07 00:28:03 · 1542 阅读 · 0 评论 -
Java编程笔记--int&String
反转整数x,设结果为resultresult=result*10+(x%10); x/=10;32位有符号整数,数值范围是 [−231, 231 − 1]Integer.MIN_VALUE;Integer.MAX_VALUE;字符串String转换为整数intint i = Integer.parseInt(s);int i = Integer.valueOf(...原创 2018-06-03 20:13:45 · 150 阅读 · 0 评论 -
Java基础笔记整理6--线程run()、start()方法
1. java Thread中,run()方法和start()方法的区别(1)start()方法 用 start方法来启动线程,是真正实现了多线程, 通过调用Thread类的start()方法来启动一个线程,这时此线程处于就绪(可运行)状态,并没有运行,一旦得到cpu时间片,就开始执行run()方法。但要注意的是,此时无需等待run()方法执行完毕,即可继续执行下面的代码。所...原创 2018-07-02 20:46:54 · 173 阅读 · 0 评论 -
Java基础笔记整理2--JVM运行时数据区域&GC&线程间通知和唤醒
1. String str = new String(“abc”),“abc”在内存中是怎么分配的?(A C)A.堆B.栈C.字符串常量区D.寄存器笔记:什么是字符串常量池JVM为了减少字符串对象的重复创建,其维护了一个特殊的内存,这段内存被成为字符串常量池或者字符串字面量池工作原理当代码中出现字面量形式创建字符串对象时,JVM首先会对这个字面量进行检查,如果字...原创 2018-06-28 20:27:24 · 431 阅读 · 0 评论 -
Java基础笔记整理3--Java堆&栈&GC&异常类&List
1.下列说法正确的是(A B)A.JAVA程序的main方法必须写在类里面B.JAVA程序中可以有多个名字为main方法C.JAVA程序中类名必须与文件名一样D.JAVA程序的main方法中,如果只有一条语句,可以不用{}(大括号)括起来笔记:A. java是强类型语言,所有的方法必须放在类里面,包括mainB. java中可以有多个重载的main方法,只有pub...原创 2018-06-29 11:13:27 · 582 阅读 · 0 评论 -
Java基础--排序
1.在排序方法中,关键码比较次数与记录地初始排列无关的是(选择排序、插入排序)。2.希尔排序又称“缩小增量排序”,即每趟只对相同增量距离的关键字进行比较,这与关键字序列初始有序或无序无关。3.一趟排序结束后不一定能够选出一个元素放在其最终位置上的是插入排序类(直接插入、希尔)。解释:A、堆排序可以把最大的或者最小的放在堆顶,所以是可以在一趟排序之后将其中一个放在最终位置的。B、...原创 2018-08-21 09:47:09 · 338 阅读 · 0 评论 -
LeetCode初尝试-简单
1. 两数之和给定一个整数数组和一个目标值,找出数组中和为目标值的两个数。你可以假设每个输入只对应一种答案,且同样的元素不能被重复利用。示例:给定 nums = [2, 7, 11, 15], target = 9因为 nums[0] + nums[1] = 2 + 7 = 9所以返回 [0, 1]class Solution { public int[] twoSum(int[] ...原创 2018-05-30 21:27:41 · 265 阅读 · 0 评论 -
栈(Stack)的实现--顺序栈--Java
java.utilClass Stack<E> java.lang.Object java.util.AbstractCollection<E> java.util.AbstractList<E> java.util.Vector<E> ...原创 2018-08-28 15:12:06 · 660 阅读 · 0 评论 -
Java基础笔记整理4--参数传递&匿名内部类&接口&抽象类
1. java语言参数之间只有值传递,包括按值调用和按引用调用。一个方法可以修改传递引用所对应的变量值,而不能修改传递值调用所对应的变量值。按值调用:包括八大基本数据类型都是按值调用。传值的时候,也就是说方法得到的是所有参数值的一个拷贝。按引用调用:数组、对象。传值时候,传递的是引用地址的拷贝,但是都是指向同一个对象。2. 方法是可以和类名同名的,和构造方法唯一的区别就是,构造方法没...原创 2018-06-29 15:34:22 · 741 阅读 · 0 评论 -
LeetCode初尝试-简单-2
20. 有效的括号给定一个只包括 '(',')','{','}','[',']' 的字符串,判断字符串是否有效。有效字符串需满足:左括号必须用相同类型的右括号闭合。左括号必须以正确的顺序闭合。注意空字符串可被认为是有效字符串。示例 1:输入: "()"输出: true示例 2:输入: "()[]{}"输出: true示例 3:输入: "(]"输出: false示例 4:输入: "([)...原创 2018-06-03 19:50:37 · 171 阅读 · 0 评论