随笔分类 - Java
摘要:JavaSE1.6为了减少获得锁和释放锁带来的性能消耗,引入了“偏向锁”和“轻量级锁”。 在JavaSE1.6中,锁一共有4种状态,级别从低到高依次是:无锁状态、偏向锁状态、轻量级锁状态和重量级锁状态,这几个状态会随着竞争情况逐渐升级。 锁可以升级但不能降级,意味着偏向锁升级成轻量级锁后不能降级成偏向锁。这种锁升级却不能降级的策略,目的是为了提高获得锁和释放锁的效率。
阅读全文
摘要:synchronized是基于Monitor来实现同步的。 Monitor 的工作机理: 线程进入同步方法中。 为了继续执行临界区代码,线程必须获取 Monitor 锁。如果获取锁成功,将成为该监视者对象的拥有者。任一时刻内,监视者对象只属于一个活动线程(The Owner) 拥有监视者对象的线程可以调用 wait() 进入等待集合(Wait Set),同时释放监视锁,进入等待状态。 其他线程调...
阅读全文
摘要:ThreadLocal ThreadLocal是一个本地线程副本变量工具类。主要用于将私有线程和该线程存放的副本对象做一个映射,各个线程之间的变量互不干扰,在高并发场景下,可以实现无状态的调用,特别适用于各个线程依赖不通的变量值完成操作的场景。 下图为ThreadLocal的内部结构图: 从上图可知ThreadLocal的结构 每个Thread线程内部都有一个Map。 Map里面存储线程本地对...
阅读全文
摘要:Java线程池ThreadPoolExecutor的构造器: public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, ...
阅读全文
摘要:Java的线程池都是通过ThreadPoolExecutor来构建。 public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, ...
阅读全文
摘要:volatile关键字有两个特性: volatile变量对所有线程的可见性,指当一条线程修改了这个变量的值,新值对于其他线程来说是可以立即得知的。 volatile变量可以禁止指令重排序优化。 因为JVM要求线程每次使用工作内存中的volatile变量时,都必须从主内存中刷新获取最新的值;执行线程每次修改工作内存中的volatile变量后也必须立刻将之同步回主内存,这样一个线程修改了volati...
阅读全文
摘要:Java内存模型规定了所有的变量都存储在主内存(MainMemory)中;线程的工作内存中保存了被该线程使用到的变量的主内存副本拷贝;线程对变量的所有操作(读取、赋值等)都必须在工作内存中进行,而不能直接读写主内存中的变量。 不同的线程之间也无法直接访问对方工作内存中的变量,线程间变量值的传递均需要通过主内存来完成,线程、主内存、工作内存三者的交互关系如图所示: 这里所讲的主内存、工作内存与通常...
阅读全文
摘要:线程池的核心参数 corePoolSize:核心池的大小。在创建了线程池后,默认情况下,线程池中并没有任何线程,而是等待有任务到来才创建线程去执行任务,除非调用了prestartAllCoreThreads()或者prestartCoreThread()方法,从这2个方法的名字就可以看出,是预创建线程的意思,即在没有任务到来之前就创建corePoolSize个线程或者一个线程。默认情况下,在创建...
阅读全文
摘要:java sleep()和wait()的区别? sleep()和wait()都能阻塞当前线程。 区别1: sleep()属于Thread类;wait()属于Object类。 区别2: 调用sleep()方法的过程中,线程不会释放对象锁。 调用wait()方法的时候,线程会放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象调用notify()方法后本线程才进入对象锁定池准备获取对象锁进入运行状态...
阅读全文
摘要:在Java语言中,数据类型分为值类型(基本数据类型)和引用类型,值类型包括int、double、byte、boolean、char等简单数据类型,引用类型包括类、接口、数组等复杂类型。 浅克隆和深克隆的主要区别在于是否支持引用类型的成员变量的复制,下面将对两者进行详细介绍。 浅clone: 在浅克隆中,如果原型对象的成员变量是值类型,将复制一份给克隆对象;如果原型对象的成员变量是引用类型,则将引用...
阅读全文
摘要:Map的key和value是否允许null? 直接写程序验证一下: import java.util.HashMap; import java.util.Hashtable; import java.util.Map; import java.util.TreeMap; import java.util.concurrent.ConcurrentHashMap; /** * @author r...
阅读全文
摘要:这次看一些关于JVM内存分析的内容。 两个程序 程序一 首先来看两个程序,这里是程序一:JVMStackTest,看下代码: package com.zhyea.robin.jvm; public class JVMStackTest { private static int count = 0; private void recur() { ++co...
阅读全文
摘要:被标题吸引进来的不要骂我。 只是一个简单的实现,随手写了来下载一部喜欢的小说的。示例中的小说只是示例,不是我的菜。 使用了jsoup。挺好用的一个工具。 有需要的话,参考下自己改吧。挺简单的,是吧。 代码如下: package com.zhyea.doggie; import java.io.File;
import java.io.FileWriter;
import java.io.IOEx...
阅读全文
摘要:先不多说,看两个题。 第一题,如下代码执行结果: package com.zhyea.test; public class Test { public static void main(String[] args) { String str = "123"; changeString(str); System.out.print...
阅读全文
摘要:java程序中的对象在运行时会出现两种类型:编译时类型和运行时类型。例如List list = new ArrayList()。其中变量list的编译时类型是List,运行时类型是ArrayList。还有更极端的类型,如通过网络通信传递过来一个对象,则这个对象的编译时类型是Object,但程序运行时又需要调用该对象运行时类型的方法。为了解决这种问题,程序需要在运行时发现对象和类的真实信息,为了解...
阅读全文
摘要:前段时间,在学习lucene的时候,遇到了读取txt文档遇到编码错误的问题。学了几个解决方案,大部分是将文件转十六进制(可以使用UE的Ctrl+H来查看),读取开头的四个标志位来判断。可是总有些文本文件无法识别(我遇到的是部分使用UTF-8编码的文件),后来发现了JCharDet。JCharDet是mozilla(就是firefox那家)的编码识别算法的Java实现,算了,这里是官网,自己看吧。 ...
阅读全文
摘要:类加载器说明 类加载器负责将.class文件加载到内存中,并为类生成一个java.lang.Class实例。 一旦一个类被加载入JVM中,同一个类就不会被再次加入了。在JVM中用来判断类的唯一性标识是:类名、类所在的包名和类加载器。 当JVM启动时,会形成由三个类加载器组成的初始类加载器层次结构: BootStrap ClassLoader:根类加载器; Extension ClassLoad...
阅读全文
摘要:对象序列化的目标是将对象保存在磁盘中或者在网络中进行传输。实现的机制是允许将对象转为与平台无关的二进制流。 java中对象的序列化机制是将允许对象转为字节序列。这些字节序列可以使Java对象脱离程序存在,从而可以保存在磁盘上,也可以在网络间传输。 对象的序列化是将一个Java对象写入IO流;与此对应的,反序列化则是从IO流中恢复一个Java对象。 实现序列化 如果要将一个java对象序列化...
阅读全文
摘要:JVM和类 调用Java命令运行Java程序时,该命令将会启动一条Java虚拟机进程,不管该Java程序启动了多少条线程,创建了多少个变量,它们都处于该Java虚拟机进程里,共享该JVM进程的内存区。当系统出现以下几种情况时,JVM进程将被终止: 程序运行到最后正常结束; 程序运行到使用System.exit()或Runtime.getRuntime.exit()代码结束程序; 程序运行过程中遇...
阅读全文
摘要:为什么使用代理服务器不需要多说了。 使用Proxy Java提供了Proxy类实现使用代理进行通信。 Proxy类的构造器Proxy(Proxy.Type type, SocketAddress sa)。其中type表示代理类型,代理类型有三种:DIRECT(表示不使用代理)、HTTP(表示使用高级协议代理比如http或FTP)、SOCKETS(表示使用sockets代理)。sa表示代理地址...
阅读全文
浙公网安备 33010602011771号