Java 从入门到放弃
文章平均质量分 61
《Java编程思想》、《Effective Java》、《深入理解 Java虚拟机》、《Java 并发编程艺术》读书笔记,以及一些来源于网络相关资料的学习
HeatDeath
Learn by doing!
展开
-
自己动手写一个死锁 Demo
/** * Author: heatdeath * Date: 2018/7/16 * Desc: */public class DeadLockDemo { private static final Object LOCK_A = new Object(); private static final Object LOCK_B = new Object();...原创 2018-07-16 16:03:23 · 2083 阅读 · 1 评论 -
尝试在子线程中获取父线程持有锁
之前有面试官问过是否可以在子线程中获取父线程所持有的锁,我根据以前看过的 ReentrantLock 的源码分析, AQS 的队首节点中保存的是成功获取同步状态 state 的线程引用,与父子线程无关,所以是不可以的今天来实际的测试一下1. ReentrantLock 测试/** * Author: heatdeath * Date: 2018/7/15 * De...原创 2018-07-15 11:45:00 · 2438 阅读 · 1 评论 -
通过 Demo 了解 LockSupport 中 park、unpark 的使用
public class LockSupportDemo { private static boolean flag = true; private static final Object lock = new Object(); private static Thread parkedThread; public static void main(String[...原创 2018-07-11 15:51:14 · 1727 阅读 · 2 评论 -
通过 Demo 理解 Condition.await()、Condition.signal()的使用方法
public class ConditionDemo { private static final ReentrantLock lock = new ReentrantLock(); private static final Condition condition = lock.newCondition(); private static boolean flag = t...原创 2018-07-11 15:36:14 · 3335 阅读 · 2 评论 -
通过 Demo 理解 Thread.sleep、Object.wait()、Object.notify()、Object.notifyAll() 之间的联系
Demo 代码:public class WaitNotifyDemo { private static boolean flag = true; private static final Object lock = new Object(); public static void main(String[] args) throws Exception { ...原创 2018-07-11 15:16:50 · 1123 阅读 · 0 评论 -
关于 Cloneable 接口 和 重写 Object.clone() 方法的尝试顺便复习深拷贝和浅拷贝
一个类如果想重写 Object 的 clone 方法,则必须实现 Cloneable 接口,否则调用 clone 方法时将会抛出 CloneNotSupportException 异常/** * Author: heatdeath * Date: 2018/7/7 * Desc: */public class CloneDemo { static class Clon...原创 2018-07-07 13:36:47 · 3226 阅读 · 1 评论 -
关于重写 equals 和 hashCode 方法对 Map.get() 方法影响的测试
未重写 hashCode 和 equalspublic class ObjectDemo { static class MyClass { public String name; } public static void main(String[] args) { MyClass myClass1 = new MyClass(); ...原创 2018-07-07 12:43:45 · 1923 阅读 · 0 评论 -
Java 中的线程池 ThreadPool
线程池主要有以下三种:SingleThreadExecutorFixedThreadPoolCachedThreadPoolSingleThreadExecutor只有一个线程的线程池, 核心线程数为 1, 最大线程数为 1,线程存活时间 0(反正也用不到…),阻塞队列使用的 LinkedBlockingQueue(一个 FIFO 队列)FixedThread...原创 2018-04-22 21:33:46 · 500 阅读 · 0 评论 -
Java 中的深拷贝与浅拷贝
clone() 是 Object 类的一个 protected 方法,如果一个类想要使用 clone() 这个方法,需要实现 Cloneable 接口,并 Override clone()(需要自己定义 clone 规则)所谓浅拷贝,就是指 Class_A 实现了 Cloneable 接口,并重写了 clone()方法,但是 Class_A 中的引用类型成员变量 ref_b 所指向的类 Cla...原创 2018-04-22 19:33:54 · 403 阅读 · 0 评论 -
JDK 1.6 与 1.8 中的 ConcurrentHashMap 学习
参考资料:1、JDK1.8逐字逐句带你理解ConcurrentHashMap https://blog.csdn.net/u012403290/article/details/676364692、Java并发编程总结4——ConcurrentHashMap在jdk1.8中的改进 https://www.cnblogs.com/everSeeker/p/5601861.html3、j...原创 2018-04-22 00:34:01 · 409 阅读 · 0 评论 -
AbstractQueuedSynchronizer 学习
参考资料:1、深入浅出AQS之独占锁模式 https://www.jianshu.com/p/71449a7d01af2、深入浅出AQS之共享锁模式 https://www.jianshu.com/p/1161d33fc1d0独占式获取过程:1、线程调用 acquire() 方法获取同步状态 state2、如果 tryAcquire() 返回为 false (获取失...原创 2018-04-21 17:35:06 · 359 阅读 · 0 评论 -
Object 的 hashCode() 、equals()、toString() 方法
hashCode()hashCode() 是 native 方法,也就是本地方法,使用 C++ 写的虽然看不懂 C++ 的代码,但是可以确定,hashCode 不是对象在内存中的地址!toString()Object.toString() 是 "类的完全限定名 + @ + 十六进制的 HashCode"equals()equals() 比较引用类型数据 ...原创 2018-04-19 21:31:13 · 265 阅读 · 0 评论 -
通过 Demo 理解 hashCode 与 equals 的关系
package com.heatdeath.object;import lombok.extern.slf4j.Slf4j;import java.util.HashMap;import java.util.Map;/** * Author: heatdeath * Date: 2018/4/19 * Desc: */@Slf4jpublic class Equa...原创 2018-04-19 21:37:34 · 255 阅读 · 0 评论 -
HashMap 的 key、value 所允许的数据类型
package com.heatdeath.object;import lombok.extern.slf4j.Slf4j;import java.util.HashMap;import java.util.Map;/** * Author: heatdeath * Date: 2018/4/19 * Desc: */@Slf4jpublic class Equa...原创 2018-04-19 21:51:15 · 20505 阅读 · 1 评论 -
Java 并发容器 —— Hashtable 与 Collections.synchronizedMap(HashMap) 的区别
Hashtable 部分源码以 Hashtable 的 put 方法为例:Hashtable 保证线程安全的方式在 方法前加上 synchronized 关键字(锁的是类的实例)Collections.synchronizedMap() 的部分源码Collections.synchronizedMap() 会调用 静态内部类SynchronizedMap 的构造器 S...原创 2018-04-16 13:18:24 · 2299 阅读 · 1 评论 -
通过 demo 理解 Java 中 try,catch,finally,return 的执行顺序
Demo-1java 编译器把unreachable statement标记为运行时错误,一个unreachable statement就是编译器决定永远不会执行它。Demo-2通过 除0 引发异常,返回 catch 块中的结果Demo-3此时 finally 块中的结果覆盖了 catch 块中的结果Demo-4注释掉 除零 异常...原创 2018-04-14 11:14:16 · 370 阅读 · 0 评论 -
Java 通过反射调用类私有方法的方法
今天在写一个类的单元测试的时候,想测试一下 一个类的私有方法在网上找了一下,应该这样写: @Test @SuppressWarnings("JavaReflectionMemberAccess") public void reqStatisticsTypeOne() throws Exception { List<String> met...原创 2018-04-11 19:47:46 · 669 阅读 · 0 评论 -
Atomic 中的 incrementAndGet与 getAndIncrement 两个方法的区别
incrementAndGet() /** * Atomically increments by one the current value. * * @return the updated value */ public final int incrementAndGet() { return unsafe.getAn...原创 2018-04-10 11:57:56 · 11357 阅读 · 4 评论 -
Java 并发编程 —— CountDownLatch 的使用方法
什么时候使用CountDownLatch什么时候使用CountDownLatch 阅读目录1 CountDownLatch2 使用 CountDownLatch 控制多个线程执行顺序场景:在学习单例模式时候,用到了锁synchronized的概念,在多线程中又用到了CountDownLatch的概念jdk:https://docs.oracle.com/jav...转载 2018-04-09 20:00:46 · 752 阅读 · 0 评论 -
基于双重检查锁定和类初始化(静态内部类)的单例模式
基于 双重检查锁定 的单例模式:public class DoubleCheckedLockingSingleton{ public static volatile DoubleCheckedLockingSingleton instance; public static DoubleCheckedLockingSingleton getInstance(){ ...原创 2018-04-05 12:17:24 · 639 阅读 · 0 评论 -
Java 深入学习(33) —— 强引用、软引用、弱引用、虚引用
在Java中,虽然不需要程序员手动去管理对象的生命周期,但是如果希望某些对象具备一定的生命周期的话(比如内存不足时JVM就会自动回收某些对象从而避免OutOfMemory的错误)就需要用到软引用和弱引用了。从Java SE2开始,就提供了四种类型的引用:强引用、软引用、弱引用和虚引用。Java中提供这四种引用类型主要有两个目的:第一是可以让程序员通过代码的方式决定某些对象的生命周期;原创 2018-02-05 10:00:16 · 365 阅读 · 0 评论 -
Java 深入学习(32) —— 注解
JDK5.0注解可以看成是Javadoc标签和Xdoclet标签的延伸和发展。在JDK5.0中,我们可以自定义这些标签,并通过Java语言的反射机制中获取类中标注的注解,完成特定的功能。 注解是代码的附属信息,它遵循一个基本原则:注解不能直接干扰程序代码的运行,无论增加或删除注解,代码都能够正常运行。Java语言解释器会忽略这些注解,而由第三方工具负责对注解进行处理。第三方工具可以转载 2018-02-04 18:08:44 · 351 阅读 · 0 评论 -
Java 并发编程(7) —— 深入理解 ThreadLocal
1 对 ThreadLocal 的理解 ThreadLocal,很多地方叫做线程本地变量,也有些地方叫做线程本地存储,其实意思差不多。可能很多朋友都知道 ThreadLocal 为变量在每个线程中都创建了一个副本,那么每个线程可以访问自己内部的副本变量。 我们还是先来看一个例子:class ConnectionManager { private static转载 2018-02-04 15:07:21 · 456 阅读 · 0 评论 -
Java 深入学习(31) —— 枚举
1 枚举类简介在某些情况下,一个类的对象时有限且固定的,如季节类,它只有春夏秋冬4个对象这种实例有限且固定的类,在 Java 中被称为枚举类;在 Java 中使用 enum 关键字来定义枚举类,其地位与 class、interface 相同;枚举类是一种特殊的类,它和普通的类一样,有自己的成员变量、成员方法、构造器 (只能使用 private 访问修饰符,所以无法从外部调用构造器,构原创 2018-02-04 12:56:33 · 335 阅读 · 0 评论 -
Java 深入学习(30) —— 泛型的实现,擦除
1 什么是擦除从以上的代码可以看出,List 和 List 在运行时事实上是相同的类型,这两种形式都被擦除成它们原生的类型。Java 泛型是使用擦除来实现的,当你在使用泛型的时候,任何具体的类型信息都会被擦除掉,你唯一知道的就是你在使用一个对象。由以上的代码可知, Class.getTypeParameters() 将返回一个 TypeVariable 对象数组,表原创 2018-02-04 18:28:46 · 325 阅读 · 0 评论 -
Java 深入学习(29) —— 泛型基础
0 简介泛型技术在 C# 和 Java 之中的使用方式看似相同,但实现上却有着根本性的分歧。C#里面泛型无论在程序源码中、编译后的IL中(Intermediate Language,中间语言,这时候泛型是一个占位符)或是运行期的CLR中都是切实存在的,List与List就是两个不同的类型,它们在系统运行期生成,有自己的虚方法表和类型数据,这种实现称为类型膨胀,基于这种方法实现的泛型被称原创 2018-01-29 15:58:18 · 413 阅读 · 0 评论 -
Java 中 BasicNameValuePair 的简单使用,以及使用 BasicNameValuePair 而不使用 Map 的原因
今天看在 Apache 的 HttpClient 时,看到一个 BasicnameValuePair 觉得奇怪,明明有现成的 Map 来存储键值对,为啥偏偏用 List 这种莫名其妙的东西呢,稍微了解了一下才发现1 简单使用BasicNameValuePair 通常用于在 Http 请求中封装用于 post 的参数名称与参数值。常见的应用如下图:public String h原创 2018-01-24 18:33:09 · 6960 阅读 · 2 评论 -
Java 深入学习(28) —— 静态代理与动态代理
代理是基本的设计模式之一,它是为了提供额外的或不同的操作,而插入的用来代替“实际”对象的对象。这些操作通常涉及与“实际”对象的通信,因此代理通常充当中间人的角色。1 静态代理代理这种设计模式其实很好理解,基本就是最简单的一个“组合”。比如说下面这个例子,我们有 RealObject 这个类,本来可以直接调用 RealObject 类的 doSomething() 和 som原创 2018-01-19 16:25:44 · 399 阅读 · 0 评论 -
Java 深入学习(27) —— 反射:运行时的类型信息
1 什么是反射反射(Reflection) 是Java 程序开发语言的特征之一,它允许运行中的 Java 程序获取类的信息,并且可以操作类或对象的内部属性。通过反射,我们可以在运行时获得程序或程序集中每一个类型的成员和成员的信息。反射的核心是JVM在运行时才动态加载类或调用方法/访问属性,它不需要事先(写代码的时候或编译期)知道运行对象是谁。2 反射的功能1.在原创 2018-01-19 09:56:29 · 942 阅读 · 0 评论 -
Java 深入学习(26) —— instanceof 与 Class 的等价性
package com.test.class_obj;class Base {}class Derived extends Base {}public class FamilyVsExactType { static void test(Object x) { System.out.println("Testing x of type " + x.getCl原创 2018-01-18 19:19:43 · 606 阅读 · 0 评论 -
Java 深入学习(25) —— 注册工厂
Factory.javapackage com.test.class_obj;public interface Factory { T create();}RegisteredFactories.javapackage com.test.class_obj;import java.util.ArrayList;import java.util.List;impo原创 2018-01-18 19:02:49 · 865 阅读 · 0 评论 -
Java 深入学习(24) —— Class 对象
1 简介类是程序的一部分,每个类都有一个 Class 对象。换言之,每当编写并且编译了一个新类,就会产生一个 Class 对象(更恰当地说,是被保存在一个同名的 .class 文件中)。所有的类都是在对其第一次使用时,动态加载到 JVM 中的。当程序创建第一个对类的静态成员的引用时,就会加载这个类。使用 new 操作符创建类的新对象也会被当做对类的静态成员的引用。一旦某个类原创 2018-01-18 16:53:28 · 399 阅读 · 0 评论 -
Java 深入学习(23) —— RTTI 和 反射 的区别
术语“RTTI”是一个特定于C ++的术语,指的是核心语言的功能——“它允许程序在运行时确定各种对象的动态类型。”术语“反射”是跨程序语言使用的通用术语,指的是程序在运行时检查和修改其对象,类型等的能力。The term "RTTI" is a C++-specific term referring to the functionality of the core language t原创 2018-01-17 09:09:06 · 582 阅读 · 0 评论 -
JVM 中的指令重排
1 指令重排的定义与意义在计算机执行指令的顺序在经过程序编译器编译之后形成的指令序列,一般而言,这个指令序列是会输出确定的结果;以确保每一次的执行都有确定的结果。但是,一般情况下,CPU和编译器为了提升程序执行的效率,会按照一定的规则允许进行指令优化,在某些情况下,这种优化会带来一些执行的逻辑问题,主要的原因是代码逻辑之间是存在一定的先后顺序,在并发执行情况下,会发生二义性,即按照不同的执行逻辑,会原创 2018-01-02 23:14:43 · 1774 阅读 · 0 评论 -
Java 并发编程(6) —— volatile 关键字
1 内存模型的相关概念 大家都知道,计算机在执行程序时,每条指令都是在CPU中执行的,而执行指令过程中,势必涉及到数据的读取和写入。由于程序运行过程中的临时数据是存放在主存(物理内存)当中的,这时就存在一个问题,由于CPU执行速度很快,而从内存读取数据和向内存写入数据的过程跟CPU执行指令的速度比起来要慢的多,因此如果任何时候对数据的操作都要通过和内存的交互来进行,会大大降低指令执行的速度。因此在原创 2018-01-02 22:58:58 · 2011 阅读 · 0 评论 -
Java 并发编程(5) —— Lock
1 synchronized 的缺陷 synchronized 是 java 中的一个关键字,也就是说是 Java 语言内置的特性。那么为什么会出现 Lock 呢? 在上面一篇文章中,我们了解到如果一个代码块被 synchronized 修饰了,当一个线程获取了对应的锁,并执行该代码块时,其他线程便只能一直等待,等待获取锁的线程释放锁,而这里获取锁的线程释放锁只会有两种情况: 1)获取锁的线程原创 2018-01-01 18:21:05 · 660 阅读 · 0 评论 -
JProfiler集成IDEA查看Java项目性能(2)
0 创建Test项目,新建Test类,创建main方法1 选中Class, profiler ‘test.main’,第一次运行设置profiler安装目录2 运行后,选择Instrumentation,可以查看详细的信息3 查看运行中的main方法内存占用情况,选中Live memory->All Objects4 查看CPU占用情况,选中CPU views->Hot Spots点击按钮5 运行中原创 2018-01-01 16:23:19 · 5050 阅读 · 0 评论 -
JProfiler 简介与 JProfiler 安装并集成 IDEA (1)
1 相关文摘JProfiler下载:https://www.ej-technologies.com/download/jprofiler/files JProfile注册码:http://www.cnblogs.com/jifeng/p/3336408.html IDE集成:http://resources.ej-technologies.com/jprofiler/help/doc/2 JPr转载 2018-01-01 16:00:29 · 4064 阅读 · 1 评论 -
Java 并发编程(4) —— synchronized 关键字
1 什么时候会出现线程安全问题? 在单线程中不会出现线程安全问题,而在多线程编程中,有可能会出现同时访问同一个资源的情况,这种资源可以是各种类型的的资源:一个变量、一个对象、一个文件、一个数据库表等,而当多个线程同时访问同一个资源的时候,就会存在一个问题: 由于每个线程执行的过程是不可控的,所以很可能导致最终的结果与实际上的愿望相违背或者直接导致程序出错。 举个简单的例子: 现在有两个线程分原创 2018-01-01 13:55:36 · 844 阅读 · 0 评论 -
Java 并发编程(3) —— Thread 类的使用
1 线程的状态 在正式学习Thread类中的具体方法之前,我们先来了解一下线程有哪些状态,这个将会有助于后面对Thread类中的方法的理解。 线程从创建到最终的消亡,要经历若干个状态。一般来说,线程包括以下这几个状态:创建(new)、就绪(runnable)、运行(running)、阻塞(blocked)、time waiting、waiting、消亡(dead)。 当需要新起一个线程来执行某原创 2018-01-01 12:51:45 · 724 阅读 · 0 评论