Volatile

Since Java 5 the volatile keyword guarantees more than just the reading from and writing to main memory of variables. Actually, the volatile keyword guarantees this:

  • If Thread A writes to a volatile variable and Thread B subsequently reads the same volatile variable, then all variables visible to Thread A before writing the volatile variable, will also be visible to Thread B after it has read the volatile variable.

  • The reading and writing instructions of volatile variables cannot be reordered by the JVM (the JVM may reorder instructions for performance reasons as long as the JVM detects no change in program behaviour from the reordering). Instructions before and after can be reordered, but the volatile read or write cannot be mixed with these instructions. Whatever instructions follow a read or write of a volatile variable are guaranteed to happen after the read or write.

Volatile is not enough to guarantee the thread safety as it cannot protect the non-atomic operations, like counter++

If two threads are both reading and writing to a shared variable, then using the volatile keyword for that is not enough. You need to use a synchronized in that case to guarantee that the reading and writing of the variable is atomic. Reading or writing a volatile variable does not block threads reading or writing.

In case only one thread reads and writes the value of a volatile variable and other threads only read the variable, then the reading threads are guaranteed to see the latest value written to the volatile variable. Without making the variable volatile, this would not be guaranteed.

Immutable Objects

final fields, which cannot be modified after the object is constructed, can be safely read through non-synchronized methods, once the object is constructed

Rules specified in https://docs.oracle.com/javase/tutorial/essential/concurrency/imstrat.html

  1. Don't provide "setter" methods — methods that modify fields or objects referred to by fields.
  2. Make all fields final and private.
  3. Don't allow subclasses to override methods. The simplest way to do this is to declare the class as final. A more sophisticated approach is to make the constructor private and construct instances in factory methods.
  4. If the instance fields include references to mutable objects, don't allow those objects to be changed:
    • Don't provide methods that modify the mutable objects.
    • Don't share references to the mutable objects. Never store references to external, mutable objects passed to the constructor; if necessary, create copies, and store references to the copies. Similarly, create copies of your internal mutable objects when necessary to avoid returning the originals in your methods.

An example of Immutable Obejct

final public class ImmutableRGB {

    // Values must be between 0 and 255.
final private int red;
final private int green;
final private int blue;
final private String name; private void check(int red,
int green,
int blue) {
if (red < 0 || red > 255
|| green < 0 || green > 255
|| blue < 0 || blue > 255) {
throw new IllegalArgumentException();
}
} public ImmutableRGB(int red,
int green,
int blue,
String name) {
check(red, green, blue);
this.red = red;
this.green = green;
this.blue = blue;
this.name = name;
} public int getRGB() {
return ((red << 16) | (green << 8) | blue);
} public String getName() {
return name;
} public ImmutableRGB invert() {
return new ImmutableRGB(255 - red,
255 - green,
255 - blue,
"Inverse of " + name);
}
}

Synchronized

Synchronized Method

public class SynchronizedCounter {
private int c = 0; public synchronized void increment() {
c++;
} public synchronized void decrement() {
c--;
} public synchronized int value() {
return c;
}
}

First, it is not possible for two invocations of synchronized methods on the same object to interleave. When one thread is executing a synchronized method for an object, all other threads that invoke synchronized methods for the same object block (suspend execution) until the first thread is done with the object.

Second, when a synchronized method exits, it automatically establishes a happens-before relationship with any subsequent invocation of a synchronized method for the same object. This guarantees that changes to the state of the object are visible to all threads.

Synchronized on methods would block the whole object, like synchronized (this) { }.

if the setValue() method in a class is synchronized but getValue() method is not, then while a thread enters the setValue() method block, other threads could also enter getValue() method block at the same time. If getValue() method is also synchronized, then only one thread could enter one of the two methods at the same time. Test codes are:

public class TestMethod {
public static void main(String[] args) {
final TestObject testObject = new TestObject(0); new Thread() {
@Override
public void run() {
testObject.setValue(1);
}
}.start(); new Thread() {
@Override
public void run() {
testObject.getValue();
System.out.println("got value");
}
}.start(); }
} class TestObject {
int value; public TestObject(int value) {
this.value = value;
} synchronized void setValue(int value) {
System.out.println("Entering the setvalue lock, waiting forever " + Thread.currentThread().getName());
this.value = value;
while (true) { }
} int getValue() {
return value;
}
}

Synchronized Block

Blocks do have advantages over methods, most of all in flexibility because you can use other object as lock whereas syncing the method would lock the complete class. This is usually the safest way to do the sunchronization.

private Object lock = new Object();

private void someInputRelatedWork() {

   synchronize(lock) { ...

   }

}

Synchronized class

synchronized (MyClass.class) { } means lock on all the objects instantiated from the MyClass.class.

Synchronized Static Method

Since a static method has no associated object, the synchronized keyword lock on the class instead of the object?

The worst solution is to put the "synchronized" keywords on the static methods, which means it will lock on all instances of this class.

One point you have to be careful about (several programmers generally fall in that trap) is that there is no link between synchronized static methods and sync'ed non static methods, ie:

class A {

static synchronized f() {...}

synchronized g() {...} #

}

Main:

A a = new A();

Thread 1:

A.f();

Thread 2:

a.g();

f() and g() are not synchronized with each other and thus can execute totally concurrently.

You might wonder what happens when a static synchronized method is invoked, since a static method is associated with a class, not an object. In this case, the thread acquires the intrinsic lock for the Class object associated with the class. Thus access to class's static fields is controlled by a lock that's distinct from the lock for any instance of the class.

Atomic Access

An atomic action is one that effectively happens all at once. An atomic action cannot stop in the middle: it either happens completely, or it doesn't happen at all. No side effects of an atomic action are visible until the action is complete.

  • Reads and writes are atomic for reference variables and for most primitive variables (all types except long and double).
  • Reads and writes are atomic for all variables declared volatile (including long and double variables).

Java Synchronization的更多相关文章

  1. Java Performance Optimization Tools and Techniques for Turbocharged Apps--reference

    Java Performance Optimization by: Pierre-Hugues Charbonneau reference:http://refcardz.dzone.com/refc ...

  2. 监视锁——Java同步的基本思想

    翻译人员: 铁锚翻译时间: 2013年11月13日原文链接: Monitors – The Basic Idea of Java synchronization如果你上过操作系统课程,你就知道监视锁( ...

  3. 锁——Java同步的基本思想

    翻译人员: 铁锚 翻译时间: 2013年11月13日 原文链接:  Monitors – The Basic Idea of Java synchronization 如果你上过操作系统课程,你就知道 ...

  4. [Java基础] Java线程复习笔记

    先说说线程和进程,现代操作系统几乎无一例外地采用进程的概念,进程之间基本上可以认为是相互独立的,共享的资源非常少.线程可以认为是轻量级的进 程,充分地利用线程可以使得同一个进程中执行多种任务.Java ...

  5. Java基础学习总结(80)——Java性能优化详解

    让Java应用程序运行是一回事,但让他们跑得快就是另外一回事了.在面对对象的环境中,性能问题就像来势凶猛的野兽.但JVM的复杂性将性能调整的复杂程度增加了一个级别.这里Refcard涵盖了JVM in ...

  6. Thread Safety in Java(java中的线程安全)

    Thread Safety in Java is a very important topic. Java provide multi-threaded environment support usi ...

  7. Top 8 Diagrams for Understanding Java

    Reference: http://www.programcreek.com/2013/09/top-8-diagrams-for-understanding-java/ A diagram is s ...

  8. 垂直打击之JVM剖析

    让Java应用程序运行是一回事,但让他们跑得快就是另外一回事了.在面对对象的环境中,性能问题就像来势凶猛的野兽.但JVM的复杂性将性能调整的复杂程度增加了一个级别.这里Refcard涵盖了JVM in ...

  9. Android 性能优化(20)多核cpu入门:SMP Primer for Android

    SMP Primer for Android 1.In this document Theory Memory consistency models Processor consistency CPU ...

随机推荐

  1. 【Egret】使用Egret开发的HTML5项目,使用本地电脑作为服务器进行移动端调试流程

    流程: 1.先开启本机IIS服务器 具体开启流程如下:http://www.jb51.net/article/29787.htm 2.添加服务器MIME类型, 按照以下两个教程把所有的MIME类型都添 ...

  2. java调试技能之dubbo调试 ---telnet

    dubbo作为一个远程调用框架,虽与同类型的框架,不知道谁优谁劣,但是就公司层面使用来说,还是很棒的.这里简单的写一下怎么使用和调试技巧,就算是作个使用总结吧,供快速使用和问题解决! dubbo是基于 ...

  3. Entity Framework技术系列之0:开篇

    小分享:我有几张阿里云优惠券,用券购买或者升级阿里云相应产品最多可以优惠五折!领券地址:https://promotion.aliyun.com/ntms/act/ambassador/shareto ...

  4. 使用opencv实现自定义卷积

    对图像进行卷积是图像处理的基本操作,最近在研究图像滤波,经常要用到自定义卷积,所以实现了一下 #include "opencv2/imgproc/imgproc.hpp" #inc ...

  5. javascript的getter和setter(转)

    显然这是一个无关IE(高级IE除外)的话题,尽管如此,有兴趣的同学还是一起来认识一下ECMAScript5标准中getter和setter的实现.在一个对象中,操作其中的属性或方法,通常运用最多的就是 ...

  6. 在github上搭建免费的博客

    github好多年前,大家都开始玩啦,我这个菜鸟近几年才开始.github不仅可以管理项目,还可以搭建博客.技术人员,一般用的博客为博客园,CSDN多一些.看到朋友们都弄一个,我也开始弄起来,先找点资 ...

  7. canvas画图

    这个元素负责在页面中设定一个区域,然后就可以通过JS动态的在这个区域中绘制图形. <canvas>由几组API构成. <canvas>还建议一个名为WebGL的3D上下文 (1 ...

  8. android 4.4.3 css hack 写法

    最近发现android在4.4.3上面出现很多怪异的现象,现在虽然没有找到原因和解决方案,但是突然间找到一个css hack写法: button{ display:none; width:$rem*4 ...

  9. 以防忘记,建立stm32工程的过程

    然后会弹出manage run -time environment的运行环境界面,必须选择的有CMSIS下的core和device下的startup,至于其它的根据你需要的外设, 在stdperiph ...

  10. TC SRM683 Div1 250

    大意是有一排石子,每一堆有a[i]个,目标状态每一堆有b[i]个,每一步可以从一堆中取出一个石子转移到相邻的一个,其中1和n也算相邻也即环形.问最少步数. 比赛的时候写了个按照步数贪心的做法,FST了 ...