Callable&Future&FutureTask介绍 直接继承Thread或者实现Runnable接口都可以创建线程,但是这两种方法都有一个问题就是:没有返回值,也就是不能获取执行完的结果。因此java1.5就提供了Callable接口来实现这一场景,而Future和FutureTask就可以和Callable接口配合起来使用。 Callable和Runnable的区别 @FunctionalInterface public interface Runnable { public abstract void run(); } @FunctionalInterface public interface Callable<V> { V call() throws Exception; } Runnable 的缺陷: 不能返回一个返回值 不能抛出 checked Exception Callable的call方法可以有返回值,可以声明抛出异常。和 Callable 配合的有一个 Future 类,通过 Future 可以了解任务执行情况,或者取消任务的.... 并发之Future Future
1、ConcurrentLinkedQueue 在JDK1.5以后,java里面提供了很多的并发容器,这里我们用的是一个queue,队列。所谓队列其实就是一个容器,就是站成一对,不管票还是人都在里面排成一堆,队列有几种,有先进先出的,还有两端的队列,还有就是栈,先进后出,先加进去的后出来。这里用了一个concurrentlinkedqueue,并发的链表队列。线程里面调用了一个poll方法,意思是往外面拿一个数据,相当于在尾巴里面拿一个,如果没有拿到,他的返回值就是空,那么就中断线程。这里面没有加锁,同样有判断,但是不会出问题。完成卖票功能这种效率是比较高的。queue里面是不能装空值。这里虽然判断和操作是一起的,但是我们没有在判断里面有任何操作,大不了反过头来再拿一边,poll底层实现是cas,这里我们就不用加锁了。 private static Queue<Integer> tickets = new ConcurrentLinkedQueue<>(); static { for (int i = 0; i < 10000; i++) { ti.... java中的并发容器 java
本文代码为java代码 一、二叉树 二叉树(Binary Tree)是n(n>=0)个结点的有限集合,该集合或者为空集(称为空二叉树),或者由一个根节点和两棵互不相交的,分别称为根节点的左子树和右子树的二叉树组成。 --《大话数据结构》 简单的说,二叉树是一种树,并且最多有2个子树。如图1-1: 代码表示: public class TreeNode { public int val; public TreeNode left; public TreeNode right; public TreeNode(int x) { val = x; } } 二、二叉树的遍历 1、前序遍历 前序遍历的顺序是,根节点->左子树->右子树,遍历子树时也按照相同的顺序,可以用递归的思想理解。遍历顺序如图2-1: 代码表示: public static void prevPrintTreeNode(TreeNode root){ if(root == null){ return; } System.out.print(root.val+" "); //运用了递归 prev.... 根据前序遍历和中序遍历结果还原二叉树 java
本文参考《深入理解JAVA虚拟机》第2版,此书JDK版本为1.7。 主动引用 java类的初始化阶段,虚拟机规范严格规定了5种情况必须立即对类进行初始化。 遇到new、getstatic、putstatic或invokestatic这4条字节码指令时,如果类没有进行过初始化,则需要先触发其初始化。 使用java.lang.reflect包的方法对类进行反射调用的时候,如果类没有进行过初始化,则需要先触发其初始化。 当初始化一个类时,如果发现其父类没有进行过初始化,则需要先触发其父类的初始化。 当虚拟机启动时,用户需要制定一个要执行的主类(包含main()方法的那个类),虚拟机会先初始化这个类。 当使用JDK1.7的动态语言支持时,如果一个java.lang.invoke.MethodHandle实例最后的解析结果REF_geStatic、REF_putStatic、REF_invokeStatic的方法句柄,并且这个方法句柄所对应的类没有进行过初始化,则需要先触发其初始化。 被动引用 除了上述5种场景,其他所有类的方式都不会触发初始化,称为被动引用。下面举3个例子来说明。 1、子....... java类的主动引用和被动引用 java