四 Synchronized

首先,一个问题:一个boolean成员变量,一个方法赋值,一个方法读值,多线程环境下,需要同步吗?

如果用同步的话,读也要用synchroized修饰,因为可见性的问题

需要同步,或者用volatile。boolean赋值和读值是原子的,但是依旧有可见性问题,否则也许读方法永远都不到最新的值。

 

Synchronized的用法:

1:修饰代码块:

       修饰的是当前的对象。

   synchronized(this){

        }

        synchronized锁住的是代码还是对象? 答案是:synchronized锁住的是括号里的对象,而不是代码。

        本方法与2相比,粒度可以更小,性能更优越一些。

 

       当没有明确的对象作为锁,只是想让一段代码同步时,可以创建一个特殊的对象来充当锁:

        class Test implements Runnable

          {  

                  private byte[] lock = new byte[0]; // 特殊的instance变量

                  public void method()

                  {

                               synchronized(lock)

                                           { // todo 同步代码块 }

                   }

                  public void run()

                  { }

           }     

      注:零长度的byte数组对象创建起来将比任何对象都经济――查看编译后的字节码:生成零长度的byte[]对象只需3条操作码,而Object lock = new Object()则需要7行操作码。

2:修饰非静态方法:

       public synchronized void test() {  

       }

      对于非static的synchronized方法,锁的就是对象本身也就是this。

      注意:当一个线程访问对象的一个synchronized(this)同步代码块时,另一个线程仍然可以访问该对象中的非synchronized(this)同步代码块

                  synchronized关键字不能继承

3:修饰静态方法:

          同步的是整个类以及所有对象

4:修一个类:

          class ClassName

          { public void method()

                         { synchronized(ClassName.class)

                                  { // todo }

                          }

           }

posted @ 2017-12-26 22:32  刘大飞  阅读(173)  评论(0编辑  收藏  举报