Synchronized 与 static synchronized的区别

1.synchronized与static synchronized 的区别

synchronized是对类的当前实例进行加锁,防止其他线程同时访问该类的该实例的所有synchronized块,注意这里是“类的当前实例”, 类的两个不同实例就没有这种约束了。那么static synchronized恰好就是要控制类的所有实例的访问了,static synchronized是限制线程同时访问jvm中该类的所有实例同时访问对应的代码快。实际上,在类中某方法或某代码块中有 synchronized,那么在生成一个该类实例后,改类也就有一个监视快,放置线程并发访问改实例synchronized保护快,而static synchronized则是所有该类的实例公用一个监视快了,也也就是两个的区别了,也就是synchronized相当于 this.synchronized,而static synchronized相当于Something.synchronized.

 一个日本作者-结成浩的《java多线程设计模式》有这样的一个列子:
      pulbic class Something(){
         public synchronized void isSyncA(){}
         public synchronized void isSyncB(){}
         public static synchronized void cSyncA(){}
         public static synchronized void cSyncB(){}
     }
那么,加入有Something类的两个实例a与b,那么下列组方法何以被1个以上线程同时访问呢
   a.   x.isSyncA()与x.isSyncB()
   b.   x.isSyncA()与y.isSyncA()
   c.   x.cSyncA()与y.cSyncB()
   d.   x.isSyncA()与Something.cSyncA()
这里,很清楚的可以判断:
   a,都是对同一个实例的synchronized域访问,因此不能被同时访问
   b,是针对不同实例的,因此可以同时被访问
   c,因为是static synchronized,所以不同实例之间仍然会被限制,相当于Something.isSyncA()与   Something.isSyncB()了,因此不能被同时访问。

那么,第d呢?,书上的 答案是可以被同时访问的,答案理由是synchronzied的是实例方法与synchronzied的类方法由于锁定(lock)不同的原因。

个人分析也就是synchronized 与static synchronized 相当于两帮派,各自管各自,相互之间就无约束了,可以被同时访问。目前还不是分清楚java内部设计synchronzied是怎么样实现的。

结论:A: synchronized static是某个类的范围,synchronized static cSync{}防止多个线程同时访问这个    类中的synchronized static 方法。它可以对类的所有对象实例起作用。

B: synchronized 是某实例的范围,synchronized isSync(){}防止多个线程同时访问这个实例中的synchronized 方法。

2.synchronized方法与synchronized代码快的区别

synchronized methods(){} 与synchronized(this){}之间没有什么区别,只是 synchronized methods(){} 便于阅读理解,而synchronized(this){}可以更精确的控制冲突限制访问区域,有时候表现更高效率。

3.synchronized关键字是不能继承的

这个在http://www.learndiary.com/archives/diaries/2910.htm一文中看到的,我想这一点也是很值得注意的,继承时子类的覆盖方法必须显示定义成synchronize

范例:

package com.rr.current2.c2_2_synchronized.teststatic;

/**
 * Created by isaac_gu on 2016/5/24.
 */
public class Test {
    public static void main(String[] args) {
        Test t = new Test();
        t.test1();
        t.test2();
        t.test3();
        t.test4();
        t.test5();
        t.test6();
    }

    /**
     * a.   x.isSyncA()与x.isSyncB()
     * 运行结果:
     * A 正在执行 isSyncA!
     * A 完成 isSyncA 的操作!
     * B 正在执行 isSyncB!
     * B 完成 isSyncB 的操作!
     * 结论: 不能被多个线程同时访问
     */
    public void test1() {
        System.out.println("************************** 1. x.isSyncA()与x.isSyncB() ***************************");
        final Something x = new Something();
        Thread threadA = new Thread(new Runnable() {
            @Override
            public void run() {
                x.isSyncA("A");
            }
        });
        Thread threadB = new Thread(new Runnable() {
            @Override
            public void run() {
                x.isSyncB("B");
            }
        });
        threadA.start();
        threadB.start();
        try {
            threadA.join();
            threadB.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }

    /**
     * x.isSyncA()与y.isSyncA() - 可以同时访问
     */
    public void test2() {
        System.out.println("************************** 2. x.isSyncA()与y.isSyncA() ***************************");
        final Something x = new Something();
        final Something y = new Something();
        Thread threadA = new Thread(new Runnable() {
            @Override
            public void run() {
                x.isSyncA("A");
            }
        });
        Thread threadB = new Thread(new Runnable() {
            @Override
            public void run() {
                y.isSyncA("B");
            }
        });
        threadA.start();
        threadB.start();
        try {
            threadA.join();
            threadB.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    /**
     * x.cSyncA()与y.cSyncB() - 不可以同时访问
     */
    public void test3() {
        System.out.println("************************** 3. x.cSyncA()与y.cSyncB() ***************************");
        final Something x = new Something();
        final Something y = new Something();
        Thread threadA = new Thread(new Runnable() {
            @Override
            public void run() {
                x.cSyncA("A");
            }
        });
        Thread threadB = new Thread(new Runnable() {
            @Override
            public void run() {
                y.cSyncB("B");
            }
        });
        threadA.start();
        threadB.start();
        try {
            threadA.join();
            threadB.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    /**
     * x.isSyncA()与Something.cSyncA() - 可以同时访问
     */
    public void test4() {
        System.out.println("************************** 4. x.isSyncA()与Something.cSyncA() ***************************");
        final Something x = new Something();
        Thread threadA = new Thread(new Runnable() {
            @Override
            public void run() {
                x.isSyncA("A");
            }
        });
        Thread threadB = new Thread(new Runnable() {
            @Override
            public void run() {
                Something.cSyncA("B");
            }
        });
        threadA.start();
        threadB.start();
        try {
            threadA.join();
            threadB.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    /**
     * x.isSyncA()与 x.normalMtd() - 可以同时访问
     */
    public void test5() {
        System.out.println("************************** 5. x.isSyncA()与 x.normalMtd() ***************************");
        final Something x = new Something();
        Thread threadA = new Thread(new Runnable() {
            @Override
            public void run() {
                x.isSyncA("A");
            }
        });
        Thread threadB = new Thread(new Runnable() {
            @Override
            public void run() {
                x.normalMtd("B");
            }
        });
        threadA.start();
        threadB.start();
        try {
            threadA.join();
            threadB.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    /**
     * x.isSyncA()与 Something.staticMtdA() - 可以同时访问
     */
    public void test6() {
        System.out.println("************************** 6. x.isSyncA()与 Something.staticMtdA() ***************************");
        final Something x = new Something();
        Thread threadA = new Thread(new Runnable() {
            @Override
            public void run() {
                x.isSyncA("A");
            }
        });
        Thread threadB = new Thread(new Runnable() {
            @Override
            public void run() {
                Something.staticMtdA("B");
            }
        });
        threadA.start();
        threadB.start();
        try {
            threadA.join();
            threadB.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }


}

Something

package com.rr.current2.c2_2_synchronized.teststatic;

import java.util.concurrent.TimeUnit;

/**
 * Created by isaac_gu on 2016/5/24.
 */
public class Something {
    public synchronized void isSyncA(String name) {
        System.out.printf("%s 正在执行 isSyncA!\n", name);
        try {
            TimeUnit.SECONDS.sleep(5);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.printf("%s 完成 isSyncA 的操作!\n", name);
    }

    public synchronized void isSyncB(String name) {
        System.out.printf("%s 正在执行 isSyncB!\n", name);
        try {
            TimeUnit.SECONDS.sleep(5);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.printf("%s 完成 isSyncB 的操作!\n", name);
    }

    public static synchronized void cSyncA(String name) {
        System.out.printf("%s 正在执行 cSyncA!\n", name);
        try {
            TimeUnit.SECONDS.sleep(5);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.printf("%s 完成 cSyncA 的操作!\n", name);
    }

    public static synchronized void cSyncB(String name) {
        System.out.printf("%s 正在执行 cSyncB!\n", name);
        try {
            TimeUnit.SECONDS.sleep(5);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.printf("%s 完成 cSyncB 的操作!\n", name);
    }

    public void normalMtd(String name) {
        System.out.printf("%s 正在执行 normalA!\n", name);
        try {
            TimeUnit.SECONDS.sleep(5);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.printf("%s 完成 normalA 的操作!\n", name);
    }

    public static void staticMtdA(String name) {
        System.out.printf("%s 正在执行 normalA!\n", name);
        try {
            TimeUnit.SECONDS.sleep(5);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.printf("%s 完成 normalA 的操作!\n", name);
    }
}

结果:

************************** 1. x.isSyncA()与x.isSyncB() ***************************
B 正在执行 isSyncB!
B 完成 isSyncB 的操作!
A 正在执行 isSyncA!
A 完成 isSyncA 的操作!
************************** 2. x.isSyncA()与y.isSyncA() ***************************
A 正在执行 isSyncA!
B 正在执行 isSyncA!
A 完成 isSyncA 的操作!
B 完成 isSyncA 的操作!
************************** 3. x.cSyncA()与y.cSyncB() ***************************
A 正在执行 cSyncA!
A 完成 cSyncA 的操作!
B 正在执行 cSyncB!
B 完成 cSyncB 的操作!
************************** 4. x.isSyncA()与Something.cSyncA() ***************************
A 正在执行 isSyncA!
B 正在执行 cSyncA!
A 完成 isSyncA 的操作!
B 完成 cSyncA 的操作!
************************** 5. x.isSyncA()与 x.normalMtd() ***************************
A 正在执行 isSyncA!
B 正在执行 normalA!
B 完成 normalA 的操作!
A 完成 isSyncA 的操作!
************************** 6. x.isSyncA()与 Something.staticMtdA() ***************************
A 正在执行 isSyncA!
B 正在执行 normalA!
B 完成 normalA 的操作!
A 完成 isSyncA 的操作!

synchronized块:

/**
     * x.bSyncA()与 x.bSyncA() - 可以同时访问
     * synchronize方法、synchronized块与static synchronized方法可以同时访问
     */
    public void test7() {
        System.out.println("************************** 7. x.bSyncA()与 x.bSyncA() ***************************");
        final Something x = new Something();
        Thread threadA = new Thread(new Runnable() {
            @Override
            public void run() {
                x.bSyncA("A");
            }
        });
        Thread threadB = new Thread(new Runnable() {
            @Override
            public void run() {
                x.bSyncB("B");
            }
        });
        Thread threadC = new Thread(new Runnable() {
            @Override
            public void run() {
                x.isSyncA("C");
            }
        });
        Thread threadD = new Thread(new Runnable() {
            @Override
            public void run() {
                Something.cSyncA("D");
            }
        });
        Thread threadE = new Thread(new Runnable() {
            @Override
            public void run() {
                x.isSyncA("E");
            }
        });
        threadA.start();
        threadB.start();
        threadC.start();
        threadD.start();
        threadE.start();
        try {
            threadA.join();
            threadB.join();
            threadC.join();
            threadD.join();
            threadE.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

结果:

A 正在执行 bSyncA!
D 正在执行 cSyncA!
B 正在执行 bSyncB!
C 正在执行 isSyncA!
A 完成 bSyncA 的操作!
C 完成 isSyncA 的操作!
B 完成 bSyncB 的操作!
D 完成 cSyncA 的操作!
E 正在执行 isSyncA!
E 完成 isSyncA 的操作!

 

转载于:https://my.oschina.net/u/659286/blog/679931

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值