Java并发(三)——Synchronized关键字和锁升级
一、Synchronized使用场景Synchronized是一个同步关键字,在某些多线程场景下,如果不进行同步会导致数据不安全,而Synchronized关键字就是用于代码同步。什么情况下会数据不安全呢,要满足两个条件:一是数据共享(临界资源),二是多线程同时访问并改变该数据。 例如: 123456789101112131415161718192021222324252627public class AccountingSync implements Runnable{ //共享资源(临界资源) static int i=0; /** * synchronized 修饰实例方法 */ public synchronized void increase(){ i++; } @Override public void run() { for(int j=0;j<1000000;j++){ increase(); ...
Java并发(二)——CountDownLatch原理分析
使用示例CountDownLatch 是一个同步工具类,它允许一个或多个线程一直等待,直到其他线程的操作执行完后再执行。在使用线程池的情况下提交任务的情况下,我们无法使用线程的join()方法,这就需要选择使用CountDowConLatch了。示例代码如下: 12345678910111213141516171819202122232425262728293031323334353637383940import java.util.concurrent.CountDowConLatch;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;public class CountDownLatchTest { // 创建一个CountDownLath实例 private static CountDownLatch countDownLatch = new CountDownLatch(2); public static void...
Java并发(一)——AQS原理分析
AQS 简单介绍AQS 的全称为(AbstractQueuedSynchronizer),这个类在 java.util.concurrent.locks 包下面。 AQS 是一个用来构建锁和同步器的框架,使用 AQS 能简单且高效地构造出应用广泛的大量的同步器,比如我们提到的 ReentrantLock,Semaphore,其他的诸如 ReentrantReadWriteLock,SynchronousQueue,FutureTask(jdk1.7) 等等皆是基于 AQS 的。当然,我们自己也能利用 AQS 非常轻松容易地构造出符合我们自己需求的同步器。 AQS原理AQS原理概览AQS 核心思想是,如果被请求的共享资源空闲,则将当前请求资源的线程设置为有效的工作线程,并且将共享资源设置为锁定状态。如果被请求的共享资源被占用,那么就需要一套线程阻塞等待以及被唤醒时锁分配的机制,这个机制 AQS 是用 CLH 队列锁实现的,即将暂时获取不到锁的线程加入到队列中。 CLH(Craig,Landin,and...
Maven依赖中的scope详解
Maven的一个设计范式是约定优于配置(convention over configuration), Maven默认的依赖配置项中,scope的默认值是compile,项目中经常傻傻的分不清,直接默认了。今天梳理一下maven的scope。 scope的分类compile默认就是compile,什么都不配置也就是意味着compile。compile表示被依赖项目需要参与当前项目的编译,当然后续的测试,运行周期也参与其中,是一个比较强的依赖。 providedprovided意味着打包的时候可以不用包进去,别的设施(如JDK或者容器)会提供。事实上该依赖理论上可以参与编译,测试,运行等周期。相当于compile,但是在打包阶段做了exclude的动作。 runntimerunntime表示被依赖项不是编译所必需的,而是执行所必需的。与compile相比,跳过编译而已,说实话在终端的项目(非开源,企业内部系统)中,和compile区别不是很大。比较常见的如JSR×××的实现,对应的API...
图解Java虚拟机系列(二)节码指令
虚拟机是一个相对于物理机的概念,这两种机器都有代码执行能力,其区别在于物理机的执行引擎是直接建立在 CPU 处理器、指令集、操作系统和硬件层面上的。 而虚拟机的执行引擎则由自己实现,因此可以制定自己的指令集和执行引擎的结构体系,而且还可以执行一些不被硬件直接支持的指令集格式。这就是虚拟机相对于物理机的优势所在。 但是缺点也比较明显,由于多了一层虚拟指令,执行虚拟机指令后还要转化为本地机器码,所以在执行效率上,虚拟机是不如物理机的。 Java 虚拟机的字节码指令由一个字节长度的操作码(Opcode)以及紧随其后的零至多个操作数(Operands)构成。 如果忽略异常处理,那么 Java 虚拟机的解释器通过下面这个伪代码的循环即可有效工作: 1234567do{ 自动计算pc寄存器以及从pc寄存器的位置取出操作码; if(存在操作数){ 取出操作数; } 执行操作码所定义的操作;} while(处理下一次循环); 由于字节码指令集限制了其操作码长度为 1 个字节(0 ~...
图解 Java 虚拟机系列(一)字节码文件结构
我们都知道 .java 文件在执行之前会编译成 .class 文件后再执行。比如下面的代码: 12345678package com.jeanboy.jvm;public class HelloWorld { public static void main(String[] args) { System.out.println("Hello World!"); }} 在 控制台 执行下面命令: $ cd JVMTraning/src/main/java/com.jeanboy.jvm/ $ javac HelloWorld 在 HelloWorld.java 的同级目录下会看到创建了一个 HelloWorld.class 文件。 将 HelloWorld.class 文件用 16 进制编辑器打开,可以看到如下内容: ClassFile 结构每个 class 文件对应一个如下所示的 ClassFile...
Java中关于try、catch、finally中的细节分析
前言阿里巴巴开发手册中有这么一条:【强制】不要在 finally 块中使用 return , 在开发过程中发现部分同学对这条规则理解不是很透彻,本文将就 try 、catch、finally 的一些问题,分析一下 try 、catch、finally 的处理流程。 首先看一个例子: 例11234567891011121314151617181920public class TryCatchFinally { public static String test() { String t = ""; try { t = "try"; return t; } catch (Exception e) { t = "catch"; return t; } finally { t =...
Java小数点数字和百分号数字之间的转换
小数点数字和百分号(百分比)需要进行两者之间相互转换。如代码: 1234567891011121314151617181920212223242526String s1 = "21.8%";String s2 = "-21.7%"; NumberFormat numberFormat = NumberFormat.getPercentInstance();try { Number n1 = numberFormat.parse(s1); Number n2 = numberFormat.parse(s2); Log.d("小数点字符串转百分数", n1.floatValue() + " , " + n2.floatValue()); // 小数点字符串转百分数: 0.218 , -0.217} catch (Exception e) { e.printStackTrace();} float f1 = 0.218f;float...