Java synchronized使用

先看測試方法:java

package com.vincent;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * Vincent 建立於 2016/5/11.
 */
public class Main {
    public static void main(String[] args) {
        ExecutorService threadPool = Executors.newCachedThreadPool();
        final SynchronizedDemo synchronizedDemo=new SynchronizedDemo();
        for (int i=0;i<5;i++){
            threadPool.execute(new Runnable() {
                public void run() {
                    synchronizedDemo.b();
                }
            });
        }
        for (int i=0;i<3;i++){
            threadPool.execute(new Runnable() {
                public void run() {
                    synchronizedDemo.a();
                }
            });

        }
    }
}
  • 多個線程同時訪問多個synchronized方法:
package com.vincent;

import java.util.concurrent.TimeUnit;

/**
 * Vincent 建立於 2016/5/11.
 */
public class SynchronizedDemo {

    private Object lock1 = new Object();
    private Object lock2 = new Object();

    long currentTimeMillis = System.currentTimeMillis();

    public synchronized void a() {
        long num = System.currentTimeMillis() - currentTimeMillis;
        System.out.println("a.num=" + num);
        try {
            TimeUnit.SECONDS.sleep(2);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public synchronized void b() {
        long num = System.currentTimeMillis() - currentTimeMillis;

        System.out.println("b.num=" + num);
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

}

輸出以下:多線程

b.num=2
a.num=1003
a.num=3003
a.num=5004
b.num=7004
b.num=8004
b.num=9004
b.num=10004

由此能夠看出:多線程在同一時刻只能有一個線程訪問對象的synchronized方法測試

  • 多線程同時訪問一個synchronized方法,一個非synchronized方法
package com.vincent;

import java.util.concurrent.TimeUnit;

/**
 * Vincent 建立於 2016/5/11.
 */
public class SynchronizedDemo {

    private Object lock1 = new Object();
    private Object lock2 = new Object();

    long currentTimeMillis = System.currentTimeMillis();

    public synchronized void a() {
        long num = System.currentTimeMillis() - currentTimeMillis;
        System.out.println("a.num=" + num);
        try {
            TimeUnit.SECONDS.sleep(2);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public void b() {
        long num = System.currentTimeMillis() - currentTimeMillis;

        System.out.println("b.num=" + num);
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

}

輸出:this

b.num=15
b.num=16
a.num=16
b.num=16
b.num=16
b.num=16
a.num=2016
a.num=4016

由此看出:若是有線程訪問synchronized方法,其餘線程訪問非synchronized方法不受影響線程

  • 多線程同時訪問多個synchronized關鍵字修飾的代碼塊
package com.vincent;

import java.util.concurrent.TimeUnit;

/**
 * Vincent 建立於 2016/5/11.
 */
public class SynchronizedDemo {

    private Object lock1 = new Object();
    private Object lock2 = new Object();

    long currentTimeMillis = System.currentTimeMillis();

    public void a() {
        synchronized (this) {
            long num = System.currentTimeMillis() - currentTimeMillis;
            System.out.println("a.num=" + num);
            try {
                TimeUnit.SECONDS.sleep(2);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public void b() {
        synchronized (this) {

            long num = System.currentTimeMillis() - currentTimeMillis;

            System.out.println("b.num=" + num);
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

}

輸出:code

b.num=1
a.num=1002
a.num=3002
a.num=5003
b.num=7003
b.num=8003
b.num=9003
b.num=10004

由此能夠看出:該用法和示例1做用相同對象

  • synchronized修飾的代碼塊使用其餘同一個對象加鎖
package com.vincent;

import java.util.concurrent.TimeUnit;

/**
 * Vincent 建立於 2016/5/11.
 */
public class SynchronizedDemo {

    private Object lock1 = new Object();
    private Object lock2 = new Object();

    long currentTimeMillis = System.currentTimeMillis();

    public void a() {
        synchronized (lock1) {
            long num = System.currentTimeMillis() - currentTimeMillis;
            System.out.println("a.num=" + num);
            try {
                TimeUnit.SECONDS.sleep(2);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public void b() {
        synchronized (lock1) {

            long num = System.currentTimeMillis() - currentTimeMillis;

            System.out.println("b.num=" + num);
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

}

輸出:it

b.num=2
a.num=1003
b.num=3003
b.num=4004
b.num=5004
b.num=6004
a.num=7004
a.num=9004

結果同1io

  • synchronized修飾的代碼塊使用其餘不一樣對象加鎖
package com.vincent;

import java.util.concurrent.TimeUnit;

/**
 * Vincent 建立於 2016/5/11.
 */
public class SynchronizedDemo {

    private Object lock1 = new Object();
    private Object lock2 = new Object();

    long currentTimeMillis = System.currentTimeMillis();

    public void a() {
        synchronized (lock1) {
            long num = System.currentTimeMillis() - currentTimeMillis;
            System.out.println("a.num=" + num);
            try {
                TimeUnit.SECONDS.sleep(2);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public void b() {
        synchronized (lock2) {

            long num = System.currentTimeMillis() - currentTimeMillis;

            System.out.println("b.num=" + num);
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

}

輸出:class

b.num=1
a.num=2
b.num=1002
b.num=2002
a.num=2003
b.num=3003
b.num=4003
a.num=4003

由此看出:訪問a和b的線程互不影響

相關文章
相關標籤/搜索