线程访问同步块/代码Java

时间:2015-10-04 17:39:33

标签: java multithreading synchronization

我正在阅读Synchronized工作。这是一个例子:

public class Singleton{

private static volatile Singleton _instance;

public static Singleton getInstance(){
   if(_instance == null){
            synchronized(Singleton.class){
              if(_instance == null)
              _instance = new Singleton();
            }
   }
   return _instance;
}

假设两个线程AB正在访问getInstance();方法, 如果线程Asynchronized块中,则线程B将跳过该块并执行下一个块/语句或将等待/阻塞,直到线程A离开synchronized阻止。

第2条什么是Singleton.class synchronized参数中的null以及何时Statement

以下class A { public synchronized void method1(){...} public synchronized void method2(){...} } 是真的吗?

  

内部锁在对象上:

method1
     

如果主题A位于threadB,则method2无法输入Repository ssh://XXX@myapp-mydomain.rhcloud.com/~/git/app.git/ The jbossews cartridge is already stopped Stopping MongoDB cartridge Stopping RockMongo cartridge Waiting for stop to finish Waiting for stop to finish Building git ref 'master', commit 9a591e1 Using Maven mirror /var/lib/openshift/XXX/app-root/runtime/repo//.openshift/config/settings.rhcloud.xml Apache Maven 3.0.4 (r1232336; 2012-12-18 14:36:37-0500) Maven home: /usr/share/java/apache-maven-3.0.4 Java version: 1.7.0_85, vendor: Oracle Corporation Java home: /usr/lib/jvm/java-1.7.0-openjdk-1.7.0.85/jre Default locale: en_US, platform encoding: ANSI_X3.4-1968 OS name: "linux", version: "2.6.32-504.34.1.el6.x86_64", arch: "i386", family: "unix" Found pom.xml... attempting to build with 'mvn --global-settings /var/lib/openshift/XXX/app-root/runtime/repo//.openshift/config/settings.rhcloud.xml clean package -Popenshift -DskipTests' [INFO] Scanning for projects... [INFO] [INFO] ------------------------------------------------------------------------ [INFO] Building myapp 1.0.0 [INFO] ------------------------------------------------------------------------ ... ... downloading lot of Maven dependencies ... [INFO] Changes detected - recompiling the module! [INFO] Compiling 20 source files to /var/lib/openshift/XXX/app-root/runtime/repo/target/classes [INFO] [INFO] --- maven-resources-plugin:2.5:testResources (default-testResources) @ myapp --- [debug] execute contextualize [INFO] Using 'UTF-8' encoding to copy filtered resources. [INFO] Copying 1 resource [INFO] [INFO] --- maven-compiler-plugin:3.3:testCompile (default-testCompile) @ myapp --- [INFO] Nothing to compile - all classes are up to date [INFO] [INFO] --- maven-surefire-plugin:2.10:test (default-test) @ myapp --- [INFO] Tests are skipped. [INFO] [INFO] --- maven-war-plugin:2.6:war (default-war) @ myapp --- ... ... downloading lot of Maven dependencies ... [INFO] Packaging webapp [INFO] Assembling webapp [myapp] in [/var/lib/openshift/XXX/app-root/runtime/repo/target/myapp-1.0.0] [INFO] Processing war project [INFO] Copying webapp webResources [/var/lib/openshift/XXX/app-root/runtime/repo/src/main/webapp] to [/var/lib/openshift/XXX/app-root/runtime/repo/target/myapp-1.0.0] [INFO] Copying webapp webResources [/var/lib/openshift/XXX/app-root/runtime/repo/src/main/webapp] to [/var/lib/openshift/XXX/app-root/runtime/repo/target/myapp-1.0.0] [INFO] Copying webapp resources [/var/lib/openshift/XXX/app-root/runtime/repo/src/main/webapp] [INFO] Webapp assembled in [4153 msecs] [INFO] Building war: /var/lib/openshift/XXX/app-root/runtime/repo/webapps/ROOT.war [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 1:03.312s [INFO] Finished at: Sun Oct 04 13:23:39 EDT 2015 [INFO] Final Memory: 24M/160M [INFO] ------------------------------------------------------------------------ Preparing build for deployment Deployment id is 686f0e29 Activating deployment Starting MongoDB cartridge Waiting for mongo to start... Starting RockMongo cartridge rm: cannot remove `/var/lib/openshift/XXX/jbossews//conf/web.xml': No such file or directory ------------------------- Git Post-Receive Result: failure Activation status: failure Activation failed for the following gears: XXX (Error activating gear: CLIENT_ERROR: Failed to execute: 'control deploy' for /var/lib/openshift/XXX/jbossews #<IO:0x00000001230388> #<IO:0x00000001230310> ) Deployment completed with status: failure postreceive failed 或任何其他同步方法。

2 个答案:

答案 0 :(得分:1)

1:线程B将等待,直到线程A将释放同步对象上的锁并执行代码,之后它将获取同步对象上的锁。

2:Singleton.class是表示该类的对象。您正在同步它,因为您的_instance - 对象为空。

public synchronized void method1(){...}

在对象上进行同步,在你调用该方法时,这意味着,如果你这样调用它,2个线程将相互等待:

final A a = new A();
new Thread(new Runnable(){
    public void run(){
        a.method1();
    }
}).start();
a.method1();

但如果你在不同的对象上调用它们,两个线程将并行执行:

A a = new A();
final A b = new A();
new Thread(new Runnable(){
    public void run(){
        b.method1();
    }
}).start();
a.method1();

最后一个问题:对,线程B不会进入方法2,因为synchronized方法锁定了对象

顺便说一下。

public synchronized void method1(){...}

相当于:

public void method1(){
    synchronized(this){
        ...
    }
}

答案 1 :(得分:0)

有关synchronized关键字的文档,请参阅here

在方法上使用synchronized一次只允许一个线程访问该方法。所有其他线程将阻塞并排队等待执行。使用此关键字时,实例对象将用作锁定以同步执行。如果您在同一个对象上调用方法,则一次只能有一个线程持有锁,因此您的语句为真。

在方法上使用synchronized关键字可能会降低性能,建议使用Java并发API,请参阅here