![](https://img-blog.csdnimg.cn/20201014180756922.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
java基础
文章平均质量分 84
spark man
crazy for coding
展开
-
从put操作看ConcurrentHashMap如何解决线程安全问题
hashmap(jdk1.8)是线程不安全的,其中一个体现是方法,我们看一下大概的逻辑:如果原来这里没有相同hash值的节点,那就new一个,其实就是说,这是一个新节点,没有hash冲突发生。假设线程A和线程B都执行操作,然后key的hash值一样,然后同时走到假设之前没有hash相同的节点存在,那么A和B线程就会都执行如此一来后执行的线程就会将先执行的覆盖掉,本来两个元素就变成了一个元素,而不会出现链表挂下去的情况。我的测试代码:为了让效果出来,我需要修改一下的源码:我让hash冲突的线程睡1秒原创 2022-06-02 11:07:38 · 717 阅读 · 0 评论 -
Thread join源码解析
Thread join源码解析join例子解析join例子join就是某个线程加入的意思,或者说,插队,可以保证线程的顺序执行。我们看一个简单的例子:public class TestJoin { public static void main(String[] args) throws InterruptedException { System.out.println("main start"); Thread t1 = new Thread(() ->原创 2022-05-27 10:38:17 · 470 阅读 · 0 评论 -
gc日志分析
gc日志轻GCFull GC轻GC先来这么一个小程序:public class TestGCMessage { public static void main(String[] args) { int size = 1024 * 1024; byte[] b1 = new byte[2 * size]; byte[] b2 = new byte[2 * size]; byte[] b3 = new byte[3 * size];原创 2021-05-07 20:18:01 · 131 阅读 · 0 评论 -
Unsafe的使用(基于例子)
Unsafeintroget unsafenew instanceprivate fieldexceptionoff heap memoryintroUnsafe是不开源的,但是它无所不能。它能申请堆外内存、cas、park和unpark、修改private变量等等的。get unsafepublic class UnsafeUtil { public static Unsafe getUnsafe() throws Exception{ Field field = Unsa原创 2020-06-30 22:13:57 · 502 阅读 · 0 评论 -
线程之间的通信
线程之间的通信使用wait和notify使用condition使用CountDownLatch使用SynchronousQueue使用wait和notify使用condition使用CountDownLatch使用SynchronousQueue原创 2020-03-04 20:39:59 · 603 阅读 · 0 评论 -
线程池阻塞
线程池的阻塞问题线程池的知识问题今天碰到一个有意思的问题,我把它抽取出来:package thread_pool;import java.util.concurrent.*;public class TestThreadPool { public static void main(String[] args) { ExecutorService threadP...原创 2020-03-03 12:45:20 · 998 阅读 · 2 评论 -
ReentrantLock的原理
我们还是制造一个计数器的线程安全问题:package reentrantlock;public class TestMySynchronizer { public static void main(String[] args) { Counter counter = new Counter(); //开10条线程对counter加数 ...原创 2020-02-04 18:07:53 · 313 阅读 · 0 评论 -
走进原子性
走进原子性问题:线程之间的协作十五年前,多核处理器是特别的系统,需要花费成百上千的美元。今天,多核处理器系统又便宜又丰富,几乎每一个主要的微处理器都对并发有内部支持。为了利用好多核的优势,软件也架构在多线程上。但是,仅仅将一个工作简单地划分为几个线程并不能发挥出硬件的优势-----你必须要确保你的线程大部分时间是在工作,而不是在等待工作,或者是在共享数据结构上等锁。问题:线程之间的协作几乎...翻译 2020-01-29 12:44:04 · 205 阅读 · 0 评论 -
布隆过滤器的推导
bloom filterintromore generalintro布隆过滤器是一种很有意思的数据结构,它的用途是检测某个元素是否在一个集合中。首先,有一个数组,它的元素全部是0,然后共有m个坑:我现在有一个集合S={x,y,z}S=\left\{ x,y,z \right\}S={x,y,z},对于每一个元素,通过3个hash函数,将其打到数组上,打中的位置设置为1。比如xxx,三次hash后,数组上就会有3个位置变为1(蓝色线条)。至于hash函数,你可以认为它对xxx做了处理,最后模上原创 2020-06-15 13:06:21 · 198 阅读 · 0 评论 -
红黑树的介绍(一)
red black tree为什么要有红黑树?什么是红黑树?为什么要有红黑树?BST(binary search tree)查询的时间复杂度是logn\log nlogn。但是,当它退化成链表的时候:查询时间复杂度就变成了O(n)O(n)O(n)。这是很糟糕的情况,虽然它还是符合二叉树的定义(左小右大)。所以,我们要限制一些规则,来让树保持平衡(尽可能的),以此保证查询效率为logn\log nlogn。红黑树就是这么一棵尽可能保持平衡的二叉搜索树。什么是红黑树?红黑树要满足四个性质原创 2020-06-29 17:39:10 · 432 阅读 · 0 评论 -
跳跃表的推导和数学证明
skip list引子地铁的例子L1的理想数值让跳跃表更快重新设计地铁线引子能够完成动态数据的增删改查最简便的数据结构是什么?是链表。链表查询的时间复杂度是O(n)。如何修改最简单的链表,能够让它查得快一点呢?我们可以多增加一些连接,让它形成网络的结构。你也可以把它改成一棵树,当然这也可以说是另一种数据结构了。我们今天要讲跳跃表,skip list。再增加一张链表,情况会变得很不同。地铁的例子某城市的地铁有两条线,一条慢线,它包含所有的车站;一条快线,它的车站是慢线的一个真子集。原创 2020-05-29 23:10:27 · 465 阅读 · 0 评论 -
手写二叉树
二叉树和双向循环链表的结构几乎一样,难点在于添加元素和遍历的时候,我们要用到递归,所以小伙伴们可以用debug走一遍,这样就能清楚看到元素存放和遍历的过程了。直接上代码public class Tree<E extends Comparable<E>> {//二叉树中的元素必须是可比较的 //根节点 private Node root; //元...原创 2019-09-27 14:06:32 · 1069 阅读 · 0 评论 -
手写经典双向循环链表、队列、栈
问:写出双向循环链表,并写出增、删、查思路:一个链表要知道从哪里开始,所以要有头,还要知道有多大,所以要有size。链表的每一个疙瘩,我们叫它节点(node),它有其本身的值,还存着上一个节点和下一个节点的引用,我们要把这些节点链起来,正着链一周,反着链一周。private Node head; private int size = 0; private class Node...原创 2019-09-27 13:46:45 · 219 阅读 · 0 评论 -
装饰器模式(io的案例)
python中的装饰器大家可能都知道,但是现在我们要说java,并且要说到java的io流。装饰器模式,是对对象的装饰,是对对象能力的扩充。它和继承是不一样的,继承是对类能力的扩充。装饰器模式同样是面向接口编程的,最重要的一点是,装饰器要包含被装饰的对象。举个例子。首先,我们要有一个抽象组件:public interface Component { void doSomething();}它定义了顶级的方法。然后有一个具体组件来实现这个抽象组件:public class Co原创 2020-06-29 22:34:14 · 364 阅读 · 0 评论 -
观察者模式推导解析
Observer patternintrocodetestintro我们在看源码的时候竟会看到类似于addListener,publishEvent,fireEvent这样的代码,这都是观察者模式。观察者模式的模型很简单,就是观察者观察被观察者,当被观察者有事件发生的时候,观察者作出反应。举个例子:妈妈、爸爸或者其他人是观察者,他们观察着被观察者,当被观察者(小孩)哭了或者是饿了,他们要分别作出应有的反应。code在这里我们还要抽象出事件这个对象,事件中,要包含事件源,即触发事件的对象是谁原创 2020-06-14 21:33:24 · 153 阅读 · 0 评论 -
建造者模式
我们在看源码的时候,会经常看到xxx.build()这样的代码。这就是设计模式中的建造者模式。建造者模式能够隐藏复杂对象的创建过程,也就是不需要我们去new。它对外暴露一个build()方法,如此我们就能拿到想要的对象。一般的builder模式灵活的builder模式举一个造房子的例子。造房子需要图纸:public abstract class Builder { abstract void stepOne(); abstract void stepTwo(); abstract void原创 2020-06-11 11:11:48 · 208 阅读 · 0 评论 -
玩转单例模式
单例模式,就是一个类只能有一个实例。单例模式的关键在于构造器私有化,这样就不能在外面new。Eager Mode/** * eager mode of singleton * load the instance as soon as the class file is loaded by classloader */public class EagerMode { pri...原创 2020-02-26 07:18:18 · 288 阅读 · 2 评论 -
proxy pattern与dynamic proxy深究
Dynamic Proxy,动态代理,你就可以想成是代购。你要法国的商品,你自己买不到,但是可以通过国内的代购公司买到。生产法国商品的原公司,就像是原对象(original object),而国内的代购公司就像是代理商(proxy),我们通过代理商(proxy)就能够拿到法国商品(调用original object的method),并且还可以对原来的法国商品进行“强化”,比如快递服务,售后服务等等...原创 2019-11-28 20:26:59 · 297 阅读 · 0 评论 -
jvm分析工具
jvm toolsjvisualvmjconsolejvisualvm给一个heap out of memory的例子:public class TestHeapSpace { public static void main(String[] args) { List<TestHeapSpace> list = new ArrayList<>(...原创 2020-03-31 20:30:43 · 120 阅读 · 0 评论 -
随便聊聊JVM
JVM的东西太多了,我们刚开始学java的时候,就会接触堆、栈,还有方法区,因为我们要知道new出来的对象放在哪里,局部变量放在哪里,static修饰的变量放在哪里。我从网上截一个图:这里有三大部分:classloaderruntime data areaexecution engineclassloader就是类加载器。比如说我这里有一个Main.java文件:package......原创 2019-12-11 18:46:18 · 489 阅读 · 1 评论 -
char的妙用
我们知道,java中,char的本质就是数,所以,它可以比较大小,可以加加减减。看一道经典的题目:如何统计字符串中大写英文字母的个数?解决办法很多很多。这里,我们看一下使用char的威力。public class TestChar { public static void main(String[] args) { String str = "ggggefefAAvBdsZZZfeRVR"; countLetters(str); } pu原创 2020-06-23 12:16:57 · 371 阅读 · 0 评论 -
binarySearch的妙用
binarySearch介绍测试介绍数组工具类Arrays有个很神奇的方法:binarySearch。它有很多重载,我们介绍一个。/** * Searches the specified array of ints for the specified value using the * binary search algorithm. The array must be sorted (as * by the {@link #sort(int[])} method)原创 2020-06-23 12:00:06 · 922 阅读 · 0 评论 -
stream流式计算的妙用
有了stream流式计算,结合着函数式接口和链式调用,对于数据的处理变得更加简单,同时增强可读性。比如我们有一个User类:@Data@AllArgsConstructor@NoArgsConstructorpublic class User { private int id; private String name; private int age;}然后有一些User对象: User user1 = new User(1,"a",12);原创 2020-07-11 18:24:43 · 463 阅读 · 0 评论 -
从lambda表达式到方法引用
比如我们有一个员工类:package com.company.lambda;public class Employee { private String name; private int age; private double salary; public String getName() { return name; } ...原创 2020-01-04 14:16:55 · 186 阅读 · 0 评论 -
nio探索
NIO进阶Blocking和Non-BlockingBlocking和Non-Blocking我们首先要解决的问题是:为什么要使用nio?nio除了叫new io之外,还叫做non-blocking io,也就是非阻塞io,可见这一块的重要性。阻塞与非阻塞,我们主要讲网络编程。传统的BIO(Blocking IO):写一个server:package nio;import jav...原创 2020-04-24 21:08:48 · 112 阅读 · 0 评论 -
nio零拷贝解析
nio zero copy传统网络数据拷贝nio网络数据传递传统网络数据拷贝传统的server和client之间的数据传输就是用一个while循环不断的读取和发送。server:public class OldServer { public static void main(String[] args) throws Exception { ServerSocket serverSocket = new ServerSocket(8899); while (原创 2020-07-09 20:29:08 · 233 阅读 · 0 评论 -
synchronize的原理之偏向锁
synchronize关键字synchronize的使用synchronize的原理synchronize的使用我们知道,当出现race condition的时候,应用就不会同步。举个例子:package sync;import org.junit.Test;import java.util.concurrent.ExecutorService;import java.util....原创 2020-01-30 14:48:54 · 676 阅读 · 0 评论