2014-06-23 54 views
0

我有一个同步方法。那么我将用长时间操作启动一个Thread,子线程也有一个同步方法,但是在子线程中的synchronized方法将保持synchronized方法的锁定,这将导致anr在我的应用中。为什么在子线程中同步方法保持主线程锁定

我的代码是:

import java.util.Date; 

public class ThreadTest { 

    static MQTTThread mThread; 

    public static void main(String[] args) { 
     for (int i = 0; i < 100; i++) { 
      System.out.println("the " + i + " - restart time = " 
        + new Date()); 
      restart(i); 
     } 
    } 

    private static synchronized void restart(int i) { 
     System.out.println("the " + i + " - restart excute " + new Date()); 
     if (null != mThread) { 
      if (!mThread.isAlive()) { 
       try { 
        System.out 
        .println("Action:restartConnectThread in mThread.runFlag)"); 

        mThread = new MQTTThread(); 
        mThread.setName("MQTTThread"); 
        mThread.start(); 
        // mqttExecutor.execute(mThread); 
       } catch (Exception e) { 
        System.out.println("!mThread.runFlag"); 
       } 
      } else { 
       System.out.println("Action:restartConnectThread - CONNECTING"); 
      } 
     } else { 
      try { 
       System.out 
       .println("Action:restartConnectThread in null thread"); 
       mThread = new MQTTThread(); 
       mThread.setName("MQTTThread"); 
       mThread.start(); 
      } catch (Exception e) { 
       System.out.println("null mThread"); 
      } 
     } 
    } 

    private static class MQTTThread extends Thread { 
     public void run() { 

      connectToServer(); 
      System.out.println("connected"); 
     } 
    } 

    public static synchronized void connectToServer() { 
     try { 
      System.out.println("Thread.sleep " + new Date()); 
      Thread.sleep(20000); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    } 
} 
+0

运行代码的结果是: – user3766493

+0

把它放在你的问题。不在评论中。 – awksp

+0

你可以在你打电话的地方写出原始的android代码吗? – carlosvin

回答

1

这是synchronized方法标准行为。

http://docs.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html

它不可能的 同一对象的同步方法来交错两个调用。当一个线程正在为一个对象执行一个同步的 方法时,所有其他线程调用同一个对象块的同步方法 直到第一个线程与该对象完成为止 。

所以代码

public synchronized void method() { 
} 

相当于

public void method() { 
    synchronized (this) { 
    } 
} 

你的目的,你应该为connectToServerrestart方法

UPD使用不同的锁定对象。对不起,我错过了,你的方法是静态的。在这种情况下,specification 8.4.3.6

一个同步方法在它执行之前获取一个监视器。 对于类(静态)方法,使用与方法类的Class对象关联的监视器。

所以你不能同时运行一个类的两个synchronized方法,即使是静态