java中如何创建不可变对象

本文翻译自:http://javarevisited.blogspot.jp/2013/03/how-to-create-immutable-class-object-java-example-tutorial.html

前言

由于不可变对象在并发和多线程环境中有非常多的优势,因此在Java中编写或创建不可变类正日益流行。不可变对象提供了比常规可变对象更多的优点,特别是在创建并发Java应用程序时。不可变对象不仅保证对象状态的安全发布,而且可以在没有任何外部同步的情况下与其它线程共享。事实上,JDK本身包含了一些不可变的类,如String,Integer和其它的包装类。对于那些不知道什么是不可变的类或对象的人,不可变对象是那些一旦创建其状态就不能改变的对象,例如:java.lang.String,一旦创建就不能修改,转为大写或小写。 String中的所有修改都会导致新对象的产生,有关更多详细信息,请参阅为什么String在Java中是不可变的。在这个Java编程教程中,我们将学习如何在Java中编写不可变类,或者如何使类不可变。顺便说一下,使类不可变在代码级别上并不难,难点是决定使哪个类可变或不可变。我还建议阅读,Java Concurrency in Practice来了解更多关于Immutable对象提供的并发效益。

过去5年Java面试题精选

前言

Time is changing and so is Java interviews. Gone are the days, when knowing the difference between String and StringBuffer can help you to go through the second round of interview, questions are becoming more advanced and interviewers are asking more deep questions. When I started my career, questions like Vector vs Array and HashMap vs Hashtable were the most popular ones and just memorizing them gives you a good chance to do well in interviews, but not anymore. Nowadays, you will get questions from the areas where not many Java programmer looks e.g. NIO, patterns, sophisticated unit testing or those which are hard to master e.g. concurrency, algorithms, data structures and coding.

java中使用锁和条件对象实现生产者-消费者模式

背景

你也可以通过使用新的Lock接口和条件变量,而不是使用synchronized关键字和waitnotify方法解决生产者消费者问题。 Lock提供了一种在Java中实现互斥和同步的替代方法。锁相对synchronized关键字的优点是众所周知的,显式锁定比synchronized关键字更加细粒度和强大,例如,锁的范围可以从一个方法到另一个方法,但是synchronized关键字的范围不能超过一个方法。条件变量是java.util.concurrent.locks.Condition类的实例,它提供类似于wait,notify和notifyAll的线程间通信方法:await(),signal()和signalAll()。因此,如果一个线程通过调用condition.await()来等待条件,那么一旦条件改变,第二个线程可以调用condition.signal()或condition.signalAll()方法来通知等待线程该醒醒了,条件已改变。如果你习惯于使用synchronized关键字进行锁定,使用Lock将使你感到痛苦,因为现在获取和释放锁变成开发人员的责任。无论如何,你可以按照这里显示的代码惯例使用锁,以避免任何并发问题。在本文中,您将学习如何通过解决传统的Producer消费者问题在Java中使用Lock和Condition变量。为了深刻理解这些新的并发概念,我还建议看看Java7并发编程手册,它是Java并发编程中最好的书其中的一本,有一些非常好的例子。

为什么wait和notify必须在同步方法或同步块中调用

本文翻译自:http://javarevisited.blogspot.jp/2011/05/wait-notify-and-notifyall-in-java.html

背景

大多数Java开发者都知道Object类中的wait,notifynotifyAll方法必须在同步方法或同步块中调用,但我们又有谁思考过为什么呢?最近我一个朋友在面试中被问道了该问题。他思考了一会说:如果我们不在同步上下文中调用这些方法我们就会收到IllegalMonitorStateException异常。他的回答在Java语言层面是没有问题的,但是面试官对这个回答并不完全满意,并希望他能对此做出更多解释。在面试结束后,他和我讨论这个问题。我想他应该告诉面试官Java中关于wait和notify之间的竞态条件,如果我们不在同步方法或同步块中调用这些方法竞态条件也可以出现。让我们看看它如何在Java程序中产生。

为何java不支持多继承

本文翻译自:http://javarevisited.blogspot.jp/2011/07/why-multiple-inheritances-are-not.html

背景

最近我一个朋友参加了一次面试。几个简单的问题过后,他被问到“为什么java不支持多继承”。随后他说,java可以通过接口来实现多继承。但是面试官继续问为什么呢?也许他只是读过相关的blog,并没有深入了解过这个问题。面试结束后,朋友向我描述了该问题并询问我的答案。这是非常经典的问题,像Why String is immutable in Java。 这两个问题之间的相似性主要是由java的创建者或设计者的设计决策驱动的。 为什么Java不支持多继承,下面两个原因是我认为有意义的答案:

mysql锁介绍(一)

数据库的读现象浅析中介绍过,在并发访问情况下,可能会出现脏读、不可重复读和幻读等读现象,为了应对这些问题,主流数据库都提供了锁机制,并引入了事务隔离级别的概念。

并发控制

在计算机科学,特别是程序设计、操作系统、多处理机和数据库等领域,并发控制(Concurrency control)是确保及时纠正由并发操作导致的错误的一种机制。

数据库管理系统(DBMS)中的并发控制的任务是确保在多个事务同时存取数据库中同一数据时不破坏事务的隔离性和统一性以及数据库的统一性。下面举例说明并发操作带来的数据不一致性问题:

现有两处火车票售票点,同时读取某一趟列车车票数据库中车票余额为 X。两处售票点同时卖出一张车票,同时修改余额为 X -1写回数据库,这样就造成了实际卖出两张火车票而数据库中的记录却只少了一张。 产生这种情况的原因是因为两个事务读入同一数据并同时修改,其中一个事务提交的结果破坏了另一个事务提交的结果,导致其数据的修改被丢失,破坏了事务的隔离性。并发控制要解决的就是这类问题。

封锁、时间戳、乐观并发控制(乐观锁)和悲观并发控制(悲观锁)是并发控制主要采用的技术手段。

当并发事务同时访问一个资源时,有可能导致数据不一致,因此需要一种机制来将数据访问顺序化,以保证数据库数据的一致性。锁就是其中的一种机制。

在计算机科学中,锁是在执行多线程时用于强行限制资源访问的同步机制,即用于在并发控制中保证对互斥要求的满足。

锁的分类(oracle)

一、按操作划分,可分为DML锁、DDL锁

二、按锁的粒度划分,可分为表级锁、行级锁、页级锁(mysql)

三、按锁级别划分,可分为共享锁、排他锁

四、按加锁方式划分,可分为自动锁、显示锁

五、按使用方式划分,可分为乐观锁、悲观锁

DML锁(data locks,数据锁),用于保护数据的完整性,其中包括行级锁(Row Locks (TX锁))、表级锁(table lock(TM锁))。 DDL锁(dictionary locks,数据字典锁),用于保护数据库对象的结构,如表、索引等的结构定义。其中包排他DDL锁(Exclusive DDL lock)、共享DDL锁(Share DDL lock)、可中断解析锁(Breakable parse locks)

诡异的java面试题TOP10

本文翻译自:

Question: What does the following Java program print?

1
2
3
4
5
public class Test { 
public static void main(String[] args){
System.out.println(Math.min(Double.MIN_VALUE, 0.0d));
}
}

答案: 这问题的迷点在于它不像Integer一样最小值是负数, DoubleMAX_VALUEMIN_VALUE都是正数。Double.MIN_VALUE2^(-1074)

java中notify和notifyall的区别

背景

曾经被问到Java中nofifynotifyAll的区别,我印象中是notify只会唤醒所有等待该对象监视器锁中的一个线程,具体唤醒哪一个线程是由具体的虚拟机实现的。notifyAll会唤醒所有的等待线程。听到答案的人表示不太满意。后来就查看JDK的文档说明看看究竟区别在哪里?文档基于oracle官方JDK8版本

|