java synchronized,不同的输出弹性

时间:2016-02-20 19:33:42

标签: java multithreading

为什么输出会有差异。 我有2个案例。 1.在第一种情况下,我使用静态函数f1和f2

Foo.class.getResource("myfile");

这是我的主要方法体:         线程t1 =新线程(         new Runnable(){public void run(){f1();}}         );

 public static synchronized void f1()
 {
     for(int i=0; i< 100; i++)
         System.out.print("A");
 }   
 public static synchronized void f2()
 {
     for(int i=0; i< 100; i++)
         System.out.print("B");
 }   

输出是      AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB

  1. 第二种情况f1和f2不是静态的

    public synchronized void f1()  {      for(int i = 0; i&lt; 100; i ++)          是System.out.print(&#34; A&#34);  }
     public synchronized void f2()  {      for(int i = 0; i&lt; 100; i ++)          是System.out.print(&#34; B&#34);  }

  2. 输出太乱了。 AAABABABBBBAAAAAAAAAABBAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBBBBBBBBAA

2 个答案:

答案 0 :(得分:2)

静态同步函数在类上同步,而非静态同步函数在实例上同步。

这意味着当这些功能是静态的时,它们会相互阻挡,而当它们没有(并且使用不同的实例)时,它们就不会。

如果您的班级被调用MyClass,那么:

public static synchronized foo() {...}

类似于:

public static foo() {
    synchronized (MyClass.class) {
        // ...
    }
}

while:

public synchronized foo() {...}

类似于:

public foo() {
    synchronized (this) {
        // ...
    }
}

通常,您希望指定要同步的内容(您想要独占的资源是什么?)并避免在类/实例上使用隐式同步,因为这个原因完全正确。

答案 1 :(得分:0)

static也会在类中应用锁定(JLS-8.4.3.6. synchronized Methods部分地说表示类(static)方法,与{{1}相关联的监视器使用方法类的对象。对于实例方法,使用与Class(调用该方法的对象)关联的监视器)。在您的情况下,您可以从this上的方法和static中移除synchronize。像

这样的东西
System.out

将强制线程在写入之前获取public void f1() { synchronized (System.out) { for (int i = 0; i < 100; i++) { System.out.print("A"); } } } public void f2() { synchronized (System.out) { for (int i = 0; i < 100; i++) { System.out.print("B"); } } } 上的锁。