Java8函数式编程(lambda表达式)
Java8函数式编程(lambda表达式)简介面向对象编程是对数据进行抽象;函数式编程是对行为进行抽象。
核心思想:使用不可变值和函数,函数对一个值进行处理,映射成另一个值。
对核心类库的改进主要包括集合类的API和新引入的流Stream。流使程序员可以站在更高的抽象层次上对集合进行操作。
示例
Lambda 表达式的 10 个示例
learn-java8
java8-tutorial
一文让你明白lambda用法与源码分析
分类
惰性求值方法
1list.stream.filter(f -> f.getName().equals("p1"));
这行代码并未做什么实际性的工作,filter知识描述了Stream,没有产生新的集合。
如果使多个条件组合,可以通过代码块{}
及早求值方法
1List<Person> resultList = list.stream().filter(f -> f.getName().equals("p1")).collect(Collectors.toList());
c ...
Java关键字
Java关键字volatilevolatile是Java最轻量级的同步机制。
特性:
可见性。变量读写直接操作主存而不是CPU Cache。当一个线程修改了volatile修饰的变量后,无论是否加锁,其他线程都可以立即看到最新的修改。
禁止指令重排序优化。
保证变量可见性,但无法保证原子性。也就是说非线程安全。
Java内存模型:
详情可参考 深入分析volatile的实现原理
synchronized线程安全,锁区域内容一次只允许一个线程执行,通过锁机制控制。
当两个并发线程访问同一个对象object中的这个synchronized(this)同步代码块时,一个时间内只能有一个线程得到执行。另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块。
然而,当一个线程访问object的一个synchronized(this)同步代码块时,另一个线程仍然可以访问该object中的非synchronized(this)同步代码块。
尤其关键的是,当一个线程访问object的一个synchronized(this)同步代码块时,其他线程对object中所有其它sy ...
Java多线程知识点
Java多线程知识点Java多线程相关的一些面试题。
线程和进程有什么区别?
一个进程是一个独立(self contained)的运行环境,它可以被看作一个程序或者一个应用。而线程是在进程中执行的一个任务。线程是进程的子集,一个进程可以有很多线程,每条线程并行执行不同的任务。不同的进程使用不同的内存空间,而所有的线程共享一片相同的内存空间。别把它和栈内存搞混,每个线程都拥有单独的栈内存用来存储本地数据。
如何在Java种实现线程?
创建线程有两种方式:1、继承 Thread 类,扩展线程。2、实现 Runnable 接口。
启动一个线程是调用run()还是start()方法?
启动一个线程是调用start()方法,使线程所代表的虚拟处理机处于可运行状态,这意味着它可以由JVM 调度并执行,这并不意味着线程就会立即运行。run()方法是线程启动后要进行回调(callback)的方法。
Thread类的sleep()方法和对象的wait()方法都可以让线程暂停执行,它们有什么区别?
sleep()方法(休眠)是线程类(Thread)的静态方法,调用此方法会让当前线程 ...
Java并发源码合集
Java并发源码合集
【死磕Java并发】—– 深入分析synchronized的实现原理
【死磕Java并发】—– 深入分析volatile的实现原理
【死磕Java并发】—– Java内存模型之happens-before
【死磕Java并发】—– Java内存模型之重排序
【死磕Java并发】—– Java内存模型之分析volatile
【死磕Java并发】—– Java内存模型之从JMM角度分析DCL
【死磕Java并发】—– Java内存模型之总结
【死磕Java并发】—– J.U.C之AQS:CLH同步队列
【死磕Java并发】—– J.U.C之AQS:同步状态的获取与释放
【死磕Java并发】—– J.U.C之AQS:阻塞和唤醒线程
【死磕Java并发】—– J.U.C之重入锁:ReentrantLock
【死磕Java并发】—– J.U.C之读写锁:ReentrantReadWriteLock
【死磕Java并发】—–J.U.C之Condition
【死磕Java并发】—- 深入分析CAS
【死磕Java并发】—- J.U.C之并发工具类:CyclicBarrier
【 ...
Java异常Exception
Java异常Exception捕获异常时需要注意 try、catch、finally 块中的控制转移语句。示例:
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111public class TryCatchFinallySample { private static int testFinallyReturn() { int i = 1; try { return i; } catch (Exception e) { return i; & ...
Java的System.getProperty()方法使用
Java的System.getProperty()方法使用
引用自java的System.getProperty()方法使用
获取环境变量通过 System.getProperty("propertyName") 可以获得环境变量设置的值。
常见的Key值有:
key值
说明
java.version
Java 运行时环境版本
java.vendor
Java 运行时环境供应商
java.vendor.url
Java 供应商的 URL
java.home
Java 安装目录
java.vm.specification.version
Java 虚拟机规范版本
java.vm.specification.vendor
Java 虚拟机规范供应商
java.vm.specification.name
Java 虚拟机规范名称
java.vm.version
Java 虚拟机实现版本
java.vm.vendor
Java 虚拟机实现供应商
java.vm.name
Java 虚拟机实现名称
java.specifi ...
NIO介绍
NIO介绍
引用自NIO介绍
简介NIO时Java 1.4引入的新特性。是对原来的Standard IO的扩展。
Standard IO时对字节流的读写,在进行IO之前,首先创建一个流对象,流对象进行读写操作都是按字节,一个字节一个字节的读或写。而NIO把IO抽象成块,类似磁盘的读写,每次IO操作的单位都是一个块,块被读入内存之后就是一个byte[],NIO一次可以读或写多个字节。
组件Selector多路复用选择器,基于“事件驱动”,其核心就是通过Selector来轮询注册在其上的Channel,当发现某个或多个Channel处于就绪状态后,从阻塞状态返回就绪的Channel的SelectionKey集合,进行I/O操作。
创建多路复用器并启动线程
12Selector selector = Selector.open();new Thread(new ReactorTask()).start();
创建Channel
123456789//打开ServerSocketChannel,用于监听客户端的连接ServerSocketChannel ssc = Ser ...
Netty长连接服务
Netty长连接服务
引用自Netty 长连接服务
Netty是什么Netty: http://netty.io/
Netty is an asynchronous event-driven network application framework for rapid development of maintainable high performance protocol servers & clients.
官方的解释最精准了,期中最吸引人的就是高性能了。但是很多人会有这样的疑问:直接用 NIO 实现的话,一定会更快吧?就像我直接手写 JDBC 虽然代码量大了点,但是一定比 iBatis 快!
但是,如果了解 Netty 后你才会发现,这个还真不一定!
利用 Netty 而不用 NIO 直接写的优势有这些:
高性能高扩展的架构设计,大部分情况下你只需要关注业务而不需要关注架构
Zero-Copy 技术尽量减少内存拷贝
为 Linux 实现 Native 版 Socket
写同一份代码,兼容 java 1.7 的 NIO2 和 1.7 之前版本的 NIO
Poole ...
ThreadLocal原理机制
ThreadLocal原理机制
参考Java多线程之隔离技术ThreadLocal源码详解
简介ThreadLocal存取的数据,总是与当前线程相关,也就是说,JVM为每个运行的线程绑定了私有的本地实例存取空间,从而为多线程环境常出现的并发访问问题提供了一种隔离机制。
ThreadLocal是如何做到为每一个线程维护变量的副本的呢?实现的思路很简单,在ThreadLocal类中有一个Map,用于存储每一个线程的变量的副本。
常用方法
T get()
返回此线程局部变量的当前线程副本中的值,如果这是线程第一次调用该方法,则创建并初始化此副本。
源码:
12345678910111213public T get() { Thread t = Thread.currentThread(); ThreadLocalMap map = getMap(t); if (map != null) { ThreadLocalMap.Entry e = map.getEntry(this); if (e != null) { ...
epoll浅析以及nio中的Selector
epoll浅析以及nio中的Selector
引用自epoll浅析以及nio中的Selector
epoll基本原理首先介绍下epoll的基本原理,网上有很多版本,这里选择一个个人觉得相对清晰的讲解(详情见reference):
首先我们来定义流的概念,一个流可以是文件,socket,pipe等等可以进行I/O操作的内核对象。
不管是文件,还是套接字,还是管道,我们都可以把他们看作流。
之后我们来讨论I/O的操作,通过read,我们可以从流中读入数据;通过write,我们可以往流写入数据。现在假定一个情形,我们需要从流中读数据,但是流中还没有数据,(典型的例子为,客户端要从socket读如数据,但是服务器还没有把数据传回来),这时候该怎么办?
阻塞:阻塞是个什么概念呢?比如某个时候你在等快递,但是你不知道快递什么时候过来,而且你没有别的事可以干(或者说接下来的事要等快递来了才能做);那么你可以去睡觉了,因为你知道快递把货送来时一定会给你打个电话(假定一定能叫醒你)。
非阻塞忙轮询:接着上面等快递的例子,如果用忙轮询的方法,那么你需要知道快递员的手机号,然后每分钟给 ...
常用Java类库
常用Java类库Runtime类
JVM虚拟机注册一个钩子,当虚拟机要关闭时,会执行预先注册的线程任务。
123456789101112Runtime.getRuntime().addShutdownHook(new Thread() { public void run() { try { logger.info("## stop the canal client"); clientTest.stop(); } catch (Throwable e) { logger.warn("##something goes wrong when stopping canal:\n{}", ExceptionUtils.getFullStackTrace(e)); } finally { logger.info("## ca ...
常见锁
常见锁基础概念:
并发(Concurrency):一个处理器“同时”处理多个任务
并行(Parallelism):多个处理器“同时”处理多个任务
互斥锁(Mutex)
同步块 synchronized block
对象锁 object.lock()
可重入锁
可重入锁,也叫做递归锁,指的是同一线程外层方法获得锁之后,内层递归方法仍然有获取该锁的代码,但不受影响。ReentrantLock和synchronized都是可重入锁。
在lock方法内,应验证线程是否为已经获得锁的线程。当unlock()第一次调用时,实际上不应释放锁。(采用计数进行统计)
可重入锁最大的特点是避免死锁。
12345678910111213141516171819202122public class Test implements Runnable{ public synchronized void get(){ System.out.println(Thread.currentThread().getId()); set(); ...
常见问题
常见问题
SimpleDateFormat不是线程安全的
使用过程中不要定义为静态全局变量。
正确使用:
123456789101112/*** 时间是否是今天*/public static boolean isToday(Long second) { if (second == null) { return false; } SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd"); String today = sf.format(System.currentTimeMillis()); String compare = sf.format(new Date(second * 1000L)); return StringUtils.equals(today, compare);}
或者使用ThreadLocal:
123456private static final ThreadLocal<DateF ...
正则表达式
正则表达式常用正则表达式
规则
表达式
一个或多个汉字
^[\u0391-\uFFE5]+$
邮政编码
^[1-9]\d{5}$
QQ号码
^[1-9]\d{4,10}$
用户名(字母开头 + 数字/字母/下划线)
^[A-Za-z][A-Za-z1-9_-]+$
手机号码
^1([358][0-9]|4[579]|66|7[0135678]|9[89])[0-9]{8}$
URL
^((http|https)://)?([\w-]+\\.)+[\w-]+(/[\w-./?%&=]*)?$
18位身份证号
^(\d{6})(18|19|20)?(\d{2})([01]\d)([0123]\d)(\d{3})(\d|X|x)?$
邮箱
^[a-zA-Z_]{1,}[0-9]{0,}@(([a-zA-z0-9]-*){1,}\\.){1, ...
深度解读Tomcat中的NIO模型
深度解读Tomcat中的NIO模型
引用自深度解读 Tomcat 中的 NIO 模型
摘要: I/O复用模型,是同步非阻塞,这里的非阻塞是指I/O读写,对应的是recvfrom操作,因为数据报文已经准备好,无需阻塞。
说它是同步,是因为,这个执行是在一个线程里面执行的。有时候,还会说它又是阻塞的,实际上是指阻塞在select上面,必须等到读就绪、写就绪等网络事件。
I/O复用模型解读Tomcat的NIO是基于I/O复用来实现的。对这点一定要清楚,不然我们的讨论就不在一个逻辑线上。下面这张图学习过I/O模型知识的一般都见过,出自《UNIX网络编程》,I/O模型一共有阻塞式I/O,非阻塞式I/O,I/O复用(select/poll/epoll),信号驱动式I/O和异步I/O。这篇文章讲的是I/O复用。
这里先来说下用户态和内核态,直白来讲,如果线程执行的是用户代码,当前线程处在用户态,如果线程执行的是内核里面的代码,当前线程处在内核态。更深层来 ...
ArrayList
ArrayList
引用自图解集合 1 :ArrayList
包含元素ArrayList包含的元素:
元素
作用
transient Object[] elementData;
ArrayList是基于数组的一个实现,elementData就是底层的数组
private int size;
ArrayList里面元素的个数,这里要注意一下,size是按照调用add、remove方法的次数进行自增或者自减的,所以add一个null进入ArrayList,size也会加1
关注点
集合关注点
结论
ArrayList是否允许空
允许
ArrayList是否允许重复数据
允许
ArrayList是否有序
有序
ArrayList是否线程安全
非线程安全
关键方法添加元素12345public boolean add(E e) { ensureCapacityInternal(size + 1); // Increments modCount!! elementData[size++] = e; return tru ...
Collection接口
Collection接口类图
引用自Java集合类: Set、List、Map、Queue使用场景梳理
Collection类的父接口Iterable是迭代器接口。实现了Iterable接口的对象允许使用foreach进行遍历,所以,所有Collection集合对象都具有”foreach可遍历性”。
Collection代表一组Object的集合,这些Object被称作Collection的元素。Collection是一个接口,用以提供规范定义,不能被实例化使用。
Collection和Map的区别Collection和Map的区别在于容器中每个位置保存的元素类别。
Collection每个位置只能保存一个元素(对象);Map保存的是”键值对”,类似于一个小型数据库,可以通过”键”找到对应的”值”。
CopyOnWriteArrayList
CopyOnWriteArrayList
引用自图解集合 3 : CopyOnWriteArrayList
CopyOnWriteArrayList位于java.util.concurrent包下,可想而知,这个类是为并发而设计的
CopyOnWriteArrayList,顾名思义,Write的时候总是要Copy,也就是说对于CopyOnWriteArrayList,任何可变的操作(add、set、remove等等)都是伴随复制这个动作的
关注点
集合关注点
结论
CopyOnWriteArrayList是否允许空
允许
CopyOnWriteArrayList是否允许重复数据
允许
CopyOnWriteArrayList是否有序
有序
CopyOnWriteArrayList是否线程安全
线程安全
添加元素对于CopyOnWriteArrayList来说,增加、删除、修改、插入的原理都是一样的,所以用增加元素来分析以下Copy’O’n’Write’Array’List的底层实现机制就可以了。
12345public static void mai ...
File类
File类
引用自java中的IO整理
初始化变量
123456private static final String FILENAME = "E:\\hello.txt";private static final String FILENAME_WITH_SEPARATOR = "E:" + File.separator + "world.txt";private static final String DIRECTORY_NAME = "E:" + File.separator + "hello" + File.separator + "world";private static final String ROOT_DIRECTORY = "E:" + File.separator;private static final String SUCCESS = "成功";private static final Stri ...
HashMap
HashMap
引用自图解集合 4 :HashMap
HashMap是一种非常常见、方便和有用的集合,是一种键值对(K-V)形式的存储结构,下面将还是用图示的方式解读HashMap的实现原理。
关注点
集合关注点
结论
HashMap是否允许空
Key和Value都允许为空
HashMap是否允许重复数据
Key重复会覆盖、Value允许重复
HashMap是否有序
无序,特别说明这个无序指的是遍历HashMap的时候,得到的元素顺序基本不可能是put的顺序
HashMap是否线程安全
非线程安全
关键方法添加数据HashMap的存储单元Entry:
123456789101112/** * Basic hash bin node, used for most entries. (See below for * TreeNode subclass, and in LinkedHashMap for its Entry subclass.) */static class Node<K,V> implements Map.Entry<K,V& ...