今日新知识点:

1、关键字volatile

  sychronized是同步锁,这个之前接触过,在类/方法或代码块前加该修饰词,即可实现线程同步;

  volatile也是一个修饰符,被volatile修饰的变量程序在调用该变量时,会调用该变量被修改后的最新的值。但这并不是用于解决并发的万能的手段,原因为:(内容转载自http://www.cnblogs.com/aigongsi/archive/2012/04/01/2429166.html)

在 java 垃圾回收整理一文中,描述了jvm运行时刻内存的分配。其中有一个内存区域是jvm虚拟机栈,每一个线程运行时都有一个线程栈,

线程栈保存了线程运行时候变量值信息。当线程访问某一个对象时候值的时候,首先通过对象的引用找到对应在堆内存的变量的值,然后把堆内存

变量的具体值load到线程本地内存中,建立一个变量副本,之后线程就不再和对象在堆内存变量值有任何关系,而是直接修改副本变量的值,

在修改完之后的某一个时刻(线程退出之前),自动把线程变量副本的值回写到对象在堆中变量。这样在堆中的对象的值就产生变化了。下面一幅图

描述这写交互

read and load 从主存复制变量到当前工作内存
use and assign  执行代码,改变共享变量值 
store and write 用工作内存数据刷新主存相关内容

其中use and assign 可以多次出现

但是这一些操作并不是原子性,也就是 在read load之后,如果主内存count变量发生修改之后,线程工作内存中的值由于已经加载,不会产生对应的变化,所以计算出来的结果会和预期不一样

对于volatile修饰的变量,jvm虚拟机只是保证从主内存加载到线程工作内存的值是最新的

例如假如线程1,线程2 在进行read,load 操作中,发现主内存中count的值都是5,那么都会加载这个最新的值

在线程1堆count进行修改之后,会write到主内存中,主内存中的count变量就会变为6

线程2由于已经进行read,load操作,在进行运算之后,也会更新主内存count的变量值为6

导致两个线程及时用volatile关键字修改之后,还是会存在并发的情况。

结论:

  volatile保证了可见性,即一个线程修改了变量,那么其他线程在下次读取该变量的时候会从内存读取而不是高速缓存。但对于已经读取该变量的线程就无能为了了,即没有保证整个读取、修改、回写的原子性。

2、StringBuilder/String的代码优化问题

  今天学习ArrayList源码的时候看到开头的一段代码,如下:

  1   public ArrayList(int i)
2 {
3 if(i < 0)
4 {
5 throw new IllegalArgumentException((new StringBuilder()).append("Illegal Capacity: ").append(i).toString());
6 } else
7 {
8 elementData = new Object[i];
9 return;
10 }
11 }

关于其中抛的一个非法声明异常,ArrayList源码都使用了StringBuilder的append()来代替了String字符串的连接符"+"来代替字符串操作。这让我很是疑惑。

经过一番百度,原来是因为,String的+连接符也是通过StringBuilder的append()来实现的,但若是直接使用,代码在运行时候,还需要进行一次对象类型转换,创建新的对象等等,既浪费运算资源,降低了运算效率,还占据了多余的内存空间。

但是最终结论是:

Java虚拟机运行的不是java源代码,而是经过编译的class字节码文件,如果留心一下,就会发现,实际上Java编译器已
经在对源代码进行编译的时候,做了代码的优化处理了,将String的+操作,替换成StringBuilder的append操作了。 所以,代码里实在没有必要为了体现自己了解+字符串连接的运算本质,大动干戈的进行替换操作了。使用String的+操作就好,剩下的,留给Java平台来解决吧。
(实际上,很多代码优化建议等等,Java编译器都已经做了优化处理了。代码更重要的还是要保持优雅的设计,与清晰的实现,良好的可读性)
												

Java学习日志(20170111)的更多相关文章

  1. java学习日志(1):命令行and小程序

    1.dos命令行,常见的命令 dir:列出当前目录下的文件以及文件夹md:创建目录rd:删除目录(必须空)cd:进入指定目录cd.. :退回到上一级目录cd/:退回到根目录del:删除文件exit:退 ...

  2. Java学习日志-01-Hello World

    1.安装JDK1.7 2.安装eclipse 3.eclipse上写第一个java程序-hello world 先建工程,再建包,养成良好的习惯,然后新建类 若不先建立包,可能会提示"The ...

  3. java学习日志---File实例:实现复制整个文件夹、解决listFiles()为null问题

    需求:将H盘下的所有文件复制到H:/All 文件夹中 思路:使用递归遍历整个目标目录 传入目标路径 判断是否是文件夹 是:调用listFiles()方法,得到File数组,重点内容接着执行1 否:复制 ...

  4. java学习日志--char和int的相互转换

    package shugen; /*ASCLL码表 * 48 数字0 * 49 1 * 50 2 * 51 3 * 52 4 * 53 5 * 54 6 * 55 7 * 56 8 * 57 9 */ ...

  5. Java学习-046-日志抓取合并后排序问题解决方案之 --- log4j 二次定制,实现日志输出添加延时10ms

    自3月25至今,已经好久没有写学习日志了,今天在写日志抓取合并的小方法,发现抓取后的日志并米有依据系统执行的日志顺序排序.日志抓取排列逻辑如下: 通过日志标识,从各个日志文件(例如 use.log,e ...

  6. Java学习-007-Log4J 日志记录配置文件详解及实例源代码

    此文主要讲述在初学 Java 时,常用的 Log4J 日志记录配置文件详解及实例源代码整理.希望能对初学 Java 编程的亲们有所帮助.若有不足之处,敬请大神指正,不胜感激!源代码测试通过日期为:20 ...

  7. Flume学习应用:Java写日志数据到MongoDB

    概述 Windows平台:Java写日志到Flume,Flume最终把日志写到MongoDB. 系统环境 操作系统:win7 64 JDK:1.6.0_43 资源下载 Maven:3.3.3下载.安装 ...

  8. Java学习笔记 DbUtils数据库查询和log4j日志输出 使用

    DbUtils使用 QueryRunner DbUtils中定义了一个数据库操作类QueryRunner,所有的数据库操作CRUD都是通过此类来完成. 此类是线程安全的 方法名 对应sql语句 exc ...

  9. 《Java学习笔记(第8版)》学习指导

    <Java学习笔记(第8版)>学习指导 目录 图书简况 学习指导 第一章 Java平台概论 第二章 从JDK到IDE 第三章 基础语法 第四章 认识对象 第五章 对象封装 第六章 继承与多 ...

随机推荐

  1. Jumony Core 3,真正的HTML引擎

    Jumony Core 3,真正的HTML引擎,正式版发布 2013-11-28 17:22 by Ivony..., 778 阅读, 18 评论, 收藏, 编辑 Jumony是一个开源项目,已经有三 ...

  2. [置顶] Android事件—单选按键和下拉按键

    在平常的开发中单选按键和下拉按键是非常常用的2个点击事件.首先介绍下单选按键 1:单选按键,单选的主键是radiogroup 这个主键也是很重要的 首先介绍下主键的布局 <?xml versio ...

  3. C#对html的操作

    1,获取相对路径的html然后保存到本地路径 /// <summary> /// Html方法 /// </summary> /// <returns></r ...

  4. bootstrap插件学习-bootstrap.dropdown.js

    bootstrap插件学习-bootstrap.dropdown.js 先看bootstrap.dropdown.js的结构 var toggle = '[data-toggle="drop ...

  5. 依赖注入(IOC)

    依赖注入(IOC) 背景介绍 在设计模式中,尤其是结构型模式很多时候解决的就是对象间的依赖关系,变依赖具体为依赖抽象.平时开发中如果发现客户程序依赖某个或某类对象,我们常常会对他们进行一次抽象,形成抽 ...

  6. Python Redis 数据复制.

    1 > 下载Python操作Redis的客户端 https://pypi.python.org/pypi/redis/2.7.6 下载完成后,参考该网站相关命令,执行安装. 2 > 下载 ...

  7. Linux中添加管理员权限问题:xxx is not in the sudoers file. This incident will be reported.

    在各个不同版本的linux中添加拥有管理员权限账户有不同的简便方式. 问题: 今天遇见将新添用户添加到root用户组后,运行sudo仍然提示 ”xxx is not in the sudoers fi ...

  8. 使用Excel背单词-高效-简单

    背单词是一个很纠结的事,想必那些走在留学路上的很多人都被英语这一关卡住了,这里,笔者就聊聊,不讲背单词的方法,只提供使用vb开发的产品和使用方法,有问题欢迎讨论. 简介:使用excel背单词,有一些人 ...

  9. 关于三星设备 Activity.onDestroy() 被调用。显示“开发者选项”

    昨天在三星的Galaxy s4上测试自己的App时,在Activity页面间跳转的时候,第一个Activity的onDestory()总是被调用,导致从第二个Activity返回的时候,第一个Acti ...

  10. java多线程并发编程与CPU时钟分配小议

    我们先来研究下JAVA的多线程的并发编程和CPU时钟振荡的关系吧 老规矩,先科普 我们的操作系统在DOS以前都是单任务的 什么是单任务呢?就是一次只能做一件事 你复制文件的时候,就不能重命名了 那么现 ...