Tag Archive for JAVA

温故知新-java中equals和==的区别

值类型:是存储在内存中的堆栈(以后简称栈  ou  shit 很久以前老是把堆栈和堆等同~英文不就很好区分吗! stack  heap!!~~我擦~)。

引用类型:变量在栈中仅仅是存储引用类型变量的地址,而其本身则存储在堆中。

==操作比较的是两个变量的值是否相等,对于引用型变量表示的是两个变量在堆中存储的地址是否相同,即栈中的内容是否相同。

equals操作表示的两个变量是否是对同一个对象的引用,即堆中的内容是否相同。

==比较的是2个对象的地址,而equals比较的是2个对象的内容。
显然,当equals为true时,==不一定为true;

一、String中的equals和==
1、
public class TestString {
public static void main(String[] args) {
String s1 = “Monday”;
String s2 = “Monday”;
}
}

Read more

温故知新-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

温故知新-HashMap和Hashtable的区别

Hashtable和HashMap类有三个重要的不同之处。第一个不同主要是历史原因。Hashtable是基于陈旧的Dictionary类的,HashMap是Java 1.2引进的Map接口的一个实现。

也 许最重要的不同是Hashtable的方法是同步的,而HashMap的方法不是。这就意味着,虽然你可以不用采取任何特殊的行为就可以在一个多线程的应 用程序中用一个Hashtable,但你必须同样地为一个HashMap提供外同步。一个方便的方法就是利用Collections类的静态的 synchronizedMap()方法,它创建一个线程安全的Map对象,并把它作为一个封装的对象来返回。这个对象的方法可以让你同步访问潜在的 HashMap。这么做的结果就是当你不需要同步时,你不能切断Hashtable中的同步(比如在一个单线程的应用程序中),而且同步增加了很多处理费 用。

第三点不同是,只有HashMap可以让你将空值作为一个表的条目的key或value。HashMap中只有一条记录可以是一 个空的key,但任意数量的条目可以是空的value。这就是说,如果在表中没有发现搜索键,或者如果发现了搜索键,但它是一个空的值,那么get()将 返回null。如果有必要,用containKey()方法来区别这两种情况。

一些资料建议,当需要同步时,用Hashtable, 反之用HashMap。但是,因为在需要时,HashMap可以被同步,HashMap的功能比Hashtable的功能更多,而且它不是基于一个陈旧的 类的,所以有人认为,在各种情况下,HashMap都优先于Hashtable。

关于Properties

Read more

温故知新-Java Map 集合类简介

Java Map 集合类简介
作者:Jack Shirazi

了解最常用的集合类型之一 Map 的基础知识以及如何针对您应用程序特有的数据优化 Map。

本文相关下载:
· Jack 的 HashMap 测试
· Oracle JDeveloper 10g

java.util 中的集合类包含 Java 中某些最常用的类。 最常用的集合类是 List 和 Map。 List 的具体实现包括 ArrayList 和 Vector,它们是可变大小的列表,比较适合构建、存储和操作任何类型对象元素列表。 List 适用于按数值索引访问元素的情形。

Map 提供了一个更通用的元素存储方法。 Map 集合类用于存储元素对(称作“键”和“值”),其中每个键映射到一个值。 从概念上而言,您可以将 List 看作是具有数值键的 Map。 而实际上,除了 List 和 Map 都在定义 java.util 中外,两者并没有直接的联系。本文将着重介绍核心 Java 发行套件中附带的 Map,同时还将介绍如何采用或实现更适用于您应用程序特定数据的专用 Map。

了解 Map 接口和方法

Java 核心类中有很多预定义的 Map 类。 在介绍具体实现之前,我们先介绍一下 Map 接口本身,以便了解所有实现的共同点。 Map 接口定义了四种类型的方法,每个 Map 都包含这些方法。 下面,我们从两个普通的方法(表 1)开始对这些方法加以介绍。

表 1: 覆盖的方法。 我们将这 Object 的这两个方法覆盖,以正确比较 Map 对象的等价性。

Read more

温故知新系列-JAVA集合类相关

郁闷死~~昨天晚上断网 害得我没发成这篇日志~~googlerobots 会不会以为我没有天天更新blog的毅力啊~~排名有靠后了!

传统的图:

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

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