Archive for 企业应用

温故知新-String 和StringBuffer,StringBuilder的区别

String是不可改变,定长;

StringBuffer是不定长,可改变,通过分配更大的内存实现,StringBuffer是线程安全的可变字符序列。可将字符串缓冲区安全地用于多个线程。可以在必要时对这些方法进行同步。

StringBuilder是单个线程使用的StringBuffer等价类,一个可变的字符序列。此类提供一个与 StringBuffer 兼容的 API,但不保证同步。该类被设计用作 StringBuffer 的一个简易替换,用在字符串缓冲区被单个线程使用的时候(这种情况很普遍)。如果可能,建议优先采用该类,因为在大多数实现中,它比 StringBuffer 要快。

在 StringBuilder 上的主要操作是 append 和 insert 方法, append 方法始终将这些字符添加到生成器的末端;而 insert 方法则在指定的点添加字符。将 StringBuilder 的实例用于多个线程是不安全的。如果需要这样的同步,则建议使用 StringBuffer。

注意:本来以为StringBuilder和StringBuffer的equals方法是可以比较两个字符串的内容是否相等,今天才发现不是这么回事。这两个类都直接继承自Object,并且没有重写equals方法。

Read more

深入理解JMM

深入理解JMM  more understanding about jmm  java memory model(本站开始做英文SEO了)

深入理解JMM的重点

JMM具体规定要JLS的 “Thread and lock”一章中,可以说这是一章非常晦涩的一个规范,要想完全把
它理解清楚,一般的辛苦是不行的.那是要”相当的~~~”的辛苦.而要把它向别人再解释清楚,那简直就
是恶梦.

作者自知无力能全面清楚地向大家说明这一章的内容,但以作者的经验,主要从以下两个方面去理解
可以改快地抓住本质.而不至于陷入”Thread and lock”的泥潭.

一.理解主存储区和线程工作存储区.

二.理解同步的两个功能.

首先要明白的问题:
1.多个线程共有的字段应该用synchronizedvolatile来保护.
2.synchronized负责线程间的互斥.即同一时候只有一个线程可以执行synchronized中的代码.
3.volatile负责线程中的变量与主存储区同步.但不负责每个线程之间的同步.

[Main Memory]与[Working Memory]

java内存模型

Main Memory是实例所在的存储区,所有实例和实例的字段都在此区域,为所有线程所共有.
Working Memory是绺个线程独自所拥有的存储区.其中有Main Memory中部分COPY.

Read more

JMM & synchronized概述

根据Java语言规范中的说明,JVM系统中存在一个

主内存(Main Memory),Java中所有的变量存储在主内存中,对于所有的线程是共享的(相当于黑板,其他人都可以看到的)。

每个线程都有自己的工作内存 (Working Memory),工作内存中保存的是主存中变量的拷贝,(相当于自己笔记本,只能自己看到),工作内存由【缓存】和【堆栈】组成,其中缓存【所谓的stack  栈?不明白啊】保存的是主存中的变量的 copy,堆栈保存的是线程局部变量。线程对所有变量的操作都是在工作内存中进行的,线程之间无法直接互相访问工作内存,变量的值得变化的传递需要主存来 完成。在JMM中通过并发线程修改的变量值,必须通过线程变量同步到主存后,其他线程才能访问到。
大体上来讲,线程对某个变量的操作可以简化成下面的步骤:
1.从主内存中复制数据到工作内存
2.执行代码,对数据进行各种操作和计算
3.把操作后的变量值重新写回主内存中

当然这样的运行顺序也是我们所期望的!但是, JVM并不保证第1步和第3步会严格按照上述次序立即执行。因为根据java语言规范的规定,线程的工作内存和主存间的数据交换是松耦合的,什么时候需要 刷新工作内存或者什么时候更新主存的内容,可以由具体的虚拟机实现自行决定【悲了个剧】。由于JVM可以对特征代码进行调优,也就改变了某些运行步骤的次序的颠倒,那 么每次线程调用变量时是直接取自己的工作存储器中的值还是先从主存储器copy再取是没有保证的,任何一种情况都可能发生。同样的,线程改变变量的值之 后,是否马上写回到主存储器上也是不可保证的,也许马上写,也许过一段时间再写。

那么,在多线程的应用场景下就会出现问题了,多个线程同时访问同一个代码 块,很有可能某个线程已经改变了某变量的值,当然现在的改变仅仅是局限于工作内存中的改变,此时JVM并不能保证将改变后的值立马写到主内存中去,也就意 味着有可能其他线程不能立马得到改变后的值,依然在旧的变量上进行各种操作和运算,最终导致不可预料的结果。
这样的情况是不是就不能避免了呢?
Java程序员都知道synchronized关键字强制实施一个互斥锁,使得被保护的代码块在同一时间只能有一个线程进入并执行。当然 synchronized还有另外一个方面的作用:在线程进入synchronized块之前,会把工作存内存中的所有内容映射到主内存上,然后把工作内 存清空再从主存储器上拷贝最新的值。而在线程退出synchronized块时,同样会把工作内存中的值映射到主内存,但此时并不会清空工作内存。这样一 来就可以强制其按照上面的顺序运行,以保证线程在执行完代码块后,工作内存中的值和主内存中的值是一致的,保证了数据的一致性!

参考:http://www.javaeye.com/topic/438068

java中的两个关键字 volatile & transient

Read more

java多线程编程-正确使用 Volatile 变量

Java™ 语言包含两种内在的同步机制:同步块(或方法)和 volatile 变量。这两种机制的提出都是为了实现代码线程的安全性。其中 Volatile 变量的同步性较差(但有时它更简单并且开销更低),而且其使用也更容易出错。在这期的 Java 理论与实践中,Brian Goetz 将介绍几种正确使用 volatile 变量的模式,并针对其适用性限制提出一些建议。

Java 语言中的 volatile 变量可以被看作是一种 “程度较轻的 synchronized”;与 synchronized 块相比,volatile 变量所需的编码较少,并且运行时开销也较少,但是它所能实现的功能也仅是 synchronized 的一部分。本文介绍了几种有效使用 volatile 变量的模式,并强调了几种不适合使用 volatile 变量的情形。

锁提供了两种主要特性:互斥(mutual exclusion)可见性(visibility

互斥 即一次只允许一个线程持有某个特定的锁,因此可使用该特性实现对共享数据的协调访问协议,这样,一次就只有一个线程能够使用该共享数据。

可见性要更加复杂 一些,它必须确保释放锁之前对共享数据做出的更改对于随后获得该锁的另一个线程是可见的【就是修改必须同步到主存的意思?】 —— 如果没有同步机制提供的这种可见性保证,线程看到的共享变量可能是修改前的值或不一致的值,这将引发许多严重问题。

Volatile 变量

Read more

java内存模型详解

内存模型 (memory model)

内存模型描述的是程序中各变量(实例域、静态域和数组元素)之间的关系,以及在实际计算机系统中将变量存储到内存和从内存取出变量这样的低层细节.

不同平台间的处理器架构将直接影响内存模型的结构.

在C或C++中, 可以利用不同操作平台下的内存模型来编写并发程序. 但是, 这带给开发人员的是, 更高的学习成本.
相比之下, java利用了自身虚拟机的优势, 使内存模型不束缚于具体的处理器架构, 真正实现了跨平台.
(针对hotspot jvm, jrockit等不同的jvm, 内存模型也会不相同)

内存模型的特征:
a, Visibility 可视性 (多核,多线程间数据的共享)
b, Ordering 有序性 (对内存进行的操作应该是有序的)

  • java 内存模型 ( java memory model )

All instance fields, static fields and array elements are stored in heap memory . Local variables ( §14.4) , formal method parameters ( §8.4.1) or exception handler parameters are never shared between threads and are unaffected by the memory model.

Read more

状态对象:数据库的替代者

这是一个实战中非常重要但是容易被忽视的概念,说它重要,是因为它比数据库重要;说它容易被忽视也是同样的原因,它经常被数据库概念替代。

如果你经验和经历中没有状态这个概念,极端地说:可能你的Java系统经验还未积累到一定程度,状态是每个Java程序员深入Java系统后必然碰到的问题。

本文我想试图表达的是:状态分两种:活动的状态对象和持久化的状态。而数据库中的数据只是状态的一种持久化结果,而Java系统 运行时,我们更多的可能是和一种活动的状态打交道,这种活动的状态存在内存中,而不是持久化到硬盘上,当然,需要时你可以通过数据库/文件持久化到硬盘上。

但是,如果你以数据库数据替代状态,那么就可能导致数据库的频繁访问,而且 你的系统会变成一个非对象化的、紧耦合、到处是分散数据块的糟糕系统。这样的系统并不比传统的两层结构好到哪里!也不会比Jsp里嵌入Java代码伪三层系统高明到什么地方。

什么是状态?

只要有对象就可能有状态,任何一个对象活动时,都有自己的状态属性,类的 字段属性极有可能成为状态,我们现在经常使用的Domain model其实就是一种 包含状态的对象,如果你对状态没有深入掌握,就不可能真正掌握对象系统特点,或者是Domain Model的执行情况。

对于初学者,经常会疑问:我是将数据放在HttpSession中还是Request中,这里 其实已经开始接触状态,一旦你接触状态,你就要开始小心,因为你可能会将内存泄漏的恶魔导引进来。

内存泄漏的恶魔爆发时刻取决于你状态的生存周期和系统并发访问量。

Read more

JAVA反射机制初窥

1.反射机制概述
Reflection是Java 程序开发语言的特征之一,它允许运行中的 Java 程序对自身进行检查,或者说”自审”,并能直接操作程序的内部属性。例如,使用它能获得 Java 类中各成员的名称并显示出来。这种动态获取类的信息以及动态调用对象的方法的功能来自于Java 语言的反射Reflection)机制。

Java 反射机制主要提供了以下功能:
在运行时判断任意一个对象所属的类。
在运行时构造任意一个类的对象。
在运行时判断任意一个类所具有的成员变量和方法。
在运行时调用任意一个对象的方法。

在JDK中,主要由以下类来实现Java反射机制,这些类都位于java.lang.reflect包中:
Class类:代表一个类。
Field 类:代表类的成员变量(成员变量也称为类的属性)。
Method类:代表类的方法。
Constructor 类:代表类的构造方法。
Array类:提供了动态创建数组,以及访问数组的元素的静态方法。[1]

Read more

JVM王者宝座谁来坐?

The next big JVM language?

There’s an interesting thread of comments related to a blog post by Stephen Colebourne, who is giving a talk at this year’s JavaOne entitled “Next Big JVM language.” In particular, he and others note that the Fantom language could be the answer (I find this interesting as Fantom really wasn’t even on my radar. Until now.). Moreover, many of the threads claim Scala to be the next big language. It seems people still prefer static typing over dynamic-ness. Either way, I got the distinct impression, based upon those individuals that left comments, which, by no means reflects the community at large, that Groovy isn’t it.

Principally, the arguments against Groovy can be summarized as its lack of performance (compared to Scala, for instance). Not to be outdone, a few folks brought up Groovy++ (which attempts to add a bit of static-ness to Groovy ostensibly to increase performance). Nevertheless, the comments are quite interesting to read if for anything that Fantom is gaining mind share perhaps at the cost of other more mainstream alternatives like Groovy.

这几年,关于谁是下一个JVM上的王者语言之争已经不是新鲜事情了。看了上面的文章,您是不是又所感慨呢?

笔者对部分上述语言接触过,下面发表一下意见:

Read more

JVM探险之Class Loader类的查找

转载自:http://www.blogjava.net/zhvfeng/archive/2010/08/17/329078.html

众所周知,所有的Java class文件都是由JVM(虚拟机)加载并执行的。深入理解JVM对于我们提高Java技术和解决Java问题都有非常大的帮助。

JVM内部主要包括内存管理和Class Loader(类加载器)两个部分。熟悉了内存管理,我们就会清楚程序在内存中是怎么分配和执行的,就能解决所有和对象相关的问题(比如Memory Leak)。理解了Class Loader,就能解决所有类找不到(比如遇到NoClassDefFoundError或ClassNotFoundException)或配置文件找不到问题。

这次我们只讨论JVM的Class Loader,下次再讨论JVM的内存管理。

Class Loader的主要作用就是负责查找类并将其加载到内存中。有趣的是,Java中的Class Loader也是由Java所写,就和普通的class一样。这就产生了一个是鸡生蛋还是蛋生鸡的问题,到底第一个class由谁来加载呢?我们稍后会来讨论这个问题。

先来看一下Class Loader所具有的特点。

1.       继承关系

虽然Class Loader也是一个Java class,但这里的继承不是指定义class时使用的extends关键字来实现的继承,而是指由属性来维持的继承关系。即通过Class Loader的构造方法或其它方法显式的设置一个父Class Loader。

Read more

无觅相关文章插件,快速提升流量