class Period implements Serializable{
private final Date start;
private final Date end;
public Period(Date start, Date end){
if (start.compareTo(end) > 0){
throw new IllegalArgumentException(start + " after "+end);
}
this.start = start;
this.end = end;
}
public Date start(){
return new Date(start.getTime());
}
public Date end(){
return new Date(end.getTime());
}
@Override
public String toString() {
return "start "+start+ " end "+end;
}
private static class PeriodProxy implements Serializable{
private final Date start;
private final Date end;
PeriodProxy(Period period){
this.start = period.start;
this.end = period.end;
}
private Object readResolve(){
return new Period(start, end);
}
}
private Object writeReplace(){
return new PeriodProxy(this);
}
private void readObject(ObjectInputStream in) throws InvalidObjectException{
throw new InvalidObjectException("Proxy required");
}
}
public class SerializationProxy {
public static void main(String[] args) throws Exception{
Calendar cal1 = Calendar.getInstance();
cal1.set(2015, Calendar.JANUARY, 1);
Calendar cal2 = Calendar.getInstance();
cal1.set(2016, Calendar.JANUARY, 1);
Period period = new Period(cal1.getTime(), cal2.getTime());
System.out.println(period);
Period deserializePeriod = serializeAndDeserialize(period);
System.out.println(deserializePeriod);
}
private static <T> T serializeAndDeserialize(T serialized) throws Exception {
File serializeFile = new File("_serialized");
// serialize
try (ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(serializeFile))) {
out.writeObject(serialized);
}
// deserialize
try (ObjectInputStream in = new ObjectInputStream(new FileInputStream(serializeFile))) {
@SuppressWarnings("unchecked")
T deserialized = (T) in.readObject();
return deserialized;
}
}
Wednesday, 20 April 2016
Effective Java Item 78: Serialization proxy
Tuesday, 19 April 2016
Effective Java Item 71: Lazy initialization, holder class, double checking
static field uses holder class
instance field uses double check
if you don't mind re-creating instance again, You can use single check
private static class ValueHolder{
static final String value = "Lazy initialized";
}
public static String getValue(){
return ValueHolder.value;
}
instance field uses double check
private volatile String value;
public String getValue(){
String result = value;
if (result == null){
synchronized (this){
result = value;
if (result == null){
value = result = "LazyInitialized";
}
}
}
return result;
}
if you don't mind re-creating instance again, You can use single check
public String getValue(){
String result = value;
if (result == null){
value = result = "LazyInitialized";
}
return result;
}
Monday, 18 April 2016
Effective Java Item 69: Synchronized map vs ConcurrentMap
Synchronized map
Throws ConcurrentModificationException
ConcurrentHashMap never throws ConcurrentModificationException
public static void main(String[] args){
Map<String, String> syncMap = Collections.synchronizedMap(new HashMap<String, String>());
syncMap.put("1","1");
syncMap.put("2","2");
syncMap.put("3","3");
for (String key : syncMap.keySet()){
addValue(syncMap);
}
}
private static void addValue(Map<String, String> map){
map.put("4", "4");
}
Throws ConcurrentModificationException
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.HashMap$HashIterator.nextNode(HashMap.java:1429)
at java.util.HashMap$KeyIterator.next(HashMap.java:1453)
ConcurrentHashMap never throws ConcurrentModificationException
Map<String, String> syncMap = new ConcurrentHashMap<>();
Sunday, 17 April 2016
Effective Java Item 66: Volatile, synchronization, and AtomicLong
volatile
Found duplicates
Correct implementation using synchronized
Correct implementation using AtomicLong
class SerialNumber{
private static volatile long nextSerialNumber = 0;
public static long nextSerialNumber(){
return nextSerialNumber++;
}
}
public class MyConcurrency extends Thread{
private static List<Long> numbers = new ArrayList<>();
private static synchronized void add(long number){
numbers.add(number);
}
public static void main(String[] args) throws Exception{
new MyConcurrency().start();
new MyConcurrency().start();
new MyConcurrency().start();
Thread.sleep(10*1000); //Make sure threads all end
Set<Long> hashSet = new HashSet<>();
for(long i : numbers) {
if(!hashSet.add(i)){
System.out.println("Has duplicate "+i);
}
}
System.out.println("Finish");
}
@Override
public void run() {
long nextSerialNumber;
do{
nextSerialNumber = SerialNumber.nextSerialNumber();
add(nextSerialNumber);
}while(nextSerialNumber < 10000);
}
}
Found duplicates
Has duplicate 4528
Has duplicate 5280
Has duplicate 7274
Has duplicate 9376
Finish
Correct implementation using synchronized
class SerialNumber{
private static long nextSerialNumber = 0;
public static synchronized long nextSerialNumber(){
return nextSerialNumber++;
}
}
Correct implementation using AtomicLong
class SerialNumber{
private static final AtomicLong nextSerialNumber = new AtomicLong();
public static long nextSerialNumber(){
return nextSerialNumber.getAndIncrement();
}
}
Saturday, 16 April 2016
Threadlocal example
Business layer can access userId without passing the parameter from web layer.
package threadlocal;
class SecurityContext {
private String userId = null;
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
}
class MyThreadLocal {
private static final ThreadLocal userThreadLocal = new ThreadLocal();
public static void set(SecurityContext user) {
userThreadLocal.set(user);
}
public static void unset() {
userThreadLocal.remove();
}
public static SecurityContext get() {
return (SecurityContext)userThreadLocal.get();
}
}
class BusinessService {
public void businessMethod() {
SecurityContext securityContext = MyThreadLocal.get();
System.out.println(securityContext.getUserId());
}
}
public class Main extends Thread{
public static void main(String[] args){
new Main().start();
new Main().start();
}
@Override
public void run() {
SecurityContext securityContext = new SecurityContext();
securityContext.setUserId(getName());
MyThreadLocal.set(securityContext);
new BusinessService().businessMethod();
MyThreadLocal.unset();
}
}
Reference: http://veerasundar.com/blog/2010/11/java-thread-local-how-to-use-and-code-sample/Effective Java Item 49: Auto boxed type NullPointerException
Seems quite innocuous, but throws NPE
Example 1
Example 2
Example 1
public static void main(String[] args){
Boolean b = null;
call(b);
}
public static void call(boolean b){
System.out.println(b);
}
Example 2
public static void main(String[] args){
Integer i = null;
if (i == 42){
System.out.println(i);
}
}
Thursday, 14 April 2016
jQuery return false; vs e.preventDefault()
return false;
is equal to
e.preventDefault();
e.stopPropagation();
e.stopImmediatePropagation();
So the lesson is never use 'return false' unless you completely understand it.
Reference: http://fuelyourcoding.com/jquery-events-stop-misusing-return-false/comment-page-2/#comment-73556
is equal to
e.preventDefault();
e.stopPropagation();
e.stopImmediatePropagation();
So the lesson is never use 'return false' unless you completely understand it.
Reference: http://fuelyourcoding.com/jquery-events-stop-misusing-return-false/comment-page-2/#comment-73556
Subscribe to:
Posts (Atom)