Java多线程之synchronized
- - CSDN博客推荐文章这里通过三个测试类阐述了synchronized应用的不同场景. 首先是最基本的synchronized Method的使用.  * @see 概述:Java中的每个对象都有一个锁(lock)或者叫做监视器(monitor) .  * @see 说明:当synchronized关键字修饰一个方法时,则该方法为同步方法 . 
 public synchronized static void function04() {//类锁
        try {
            Test05.class.wait();//本类的wait池
        } catch (InterruptedException e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        }
    }
    public void function02() {
        synchronized (lock) {//lock锁
            try {
                lock.wait();//同样为lock锁的wait池
            } catch (InterruptedException e) {
                e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
            }
        }
    }| 
      
  | 
    
      可见性  | 
    
      互斥性  | 
| 
      synchronized  | 
    
      块可见  | 
    
      块互斥  | 
| 
      volatile  | 
    
      变量可见  | 
    
      变量互斥(无意义)  | 
| 
      无锁编程(Unsafe)  | 
    
      变量可见  | 
    
      不保证  | 
/**
 * Created with IntelliJ IDEA.
 * User: yangzl2008
 * Date: 14-10-25
 * Time: 下午8:31
 * To change this template use File | Settings | File Templates.
 */
public class TeshSynchronized {
    Object lock = new Object();
    public synchronized void function01() {
    }
    public void function02() {
        synchronized (lock) {
        }
    }
    public void function03() {
        synchronized (this) {
        }
    }
    public synchronized static void function04() {
    }
    public void function05() {
        synchronized (TeshSynchronized.class) {
        }
    }
}| 
      
  | 
    
      同一对象  | 
    
      不同对象但同一类  | 
| 
      对象锁  | 
    
      多线程互斥  | 
    
      多线程不互斥  | 
| 
      类锁  | 
    
      多线程互斥  | 
    
      多线程互斥  | 
/**
 * Created with IntelliJ IDEA.
 * User: yangzl2008
 * Date: 14-10-26
 * Time: 下午10:09
 * To change this template use File | Settings | File Templates.
 */
public class TestVolatile {
    private volatile int a1;  //多线程可见
    private int a2;   //多线程有问题
    private int a3;
    public int getA1() {
        return a1;
    }
    public void setA1(int a1) {
        this.a1 = a1;
    }
    public int getA2() {
        return a2;
    }
    public void setA2(int a2) {
        this.a2 = a2;
    }
    public int getA3() {
        return a3;
    }
    public synchronized void setA3(int a3) {
        this.a3 = a3;
    }
}  /**
 * Created with IntelliJ IDEA.
 * User: yangzl2008
 * Date: 14-10-26
 * Time: 下午10:21
 * To change this template use File | Settings | File Templates.
 */
public class TestVolatile2 {
    volatile int count;
    Map<String, String> map = new ConcurrentHashMap<String, String>();
    public void addContent(String key, String value) {
        if (count < 100) {
            map.put(key, value);
            count++;
        }
    }
    @Test
    public void testAddContent() throws Exception {
        ExecutorService executorService = Executors.newFixedThreadPool(10);
        for (int i = 0; i < 10; i++) {
            executorService.execute(new AddContentTask());
        }
        // 关闭启动线程
        executorService.shutdown();
        // 等待子线程结束,再继续执行下面的代码
        executorService.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS);
        System.out.println(map.size());
    }
    private final class AddContentTask implements Runnable {
        @Override
        public void run() {
            //每个线程放11次
            for (int i = 0; i <= 10; i++) {
                addContent(Thread.currentThread().getName() + " " + System.currentTimeMillis() + " " + i, "value");
            }
        }
    }
}以上判断count判断到达100后,就无法再向map当中放东西,但实际上,map当中的数量绝大多数情况下是大于100的。因此,volatile只能保证变量的可见性,而并不能保证块的互斥性,在某些情况下,其是无法代替synchronized的。   static {
      try {
        valueOffset = unsafe.objectFieldOffset
            (AtomicInteger.class.getDeclaredField("value"));
      } catch (Exception ex) { throw new Error(ex); }
    }
    private volatile int value;在我们调用getAndIncrement时,其代码如下: public final int getAndIncrement() {
        for (;;) {
            int current = get();
            int next = current + 1;
            if (compareAndSet(current, next))
                return current;
        }
    }compareAndSet的代码如下:public final boolean compareAndSet(int expect, int update) {
	return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
    }其中unsafe.compareAndSwapInt(this, valueOffset, expect, update);是一个本地方法。