2012-10-05 27 views
1

我是新来的Android编程和“之前已经研究不透的Java。我如何使用​​以确保static variables线程安全真的很困惑:Java中,正确使用静态变量,以避免死锁 - 同步

我通常会创建一个名为Utils类有一些static functions其中最具借我的所有其他类所需要的时间。这是从我的课程中保留重复代码的正确方法。

我总是遇到与使用数据库的问题。当我创建了某些数据库sqliteHelper类,并尝试从说,一个活动和后台服务来管理数据库,我通常会 陷入困境。如果我用的辅助类的局部对象,我要进入数据库的死锁最大时容易出现两个辅助对象试图获取写锁在一起。

为了走出这一困境的,我在utils类创建辅助类的static实例。现在对数据库进行任何操作我的行为和我的服务做以下的事情:

public class Utils{ 
      public static MDatabaseHelper mHelper; 
      public static void instantiateHelper(Context context){ 
      if(mHelper==null) 
       mHelper=new MDatabaseHelper(context); 

      } 
    } 



    public class mActivity extends Activity{ 
    public void insert some item in database(final Item item) // this method is called in the Activity at some time 
    (new Thread(){ 
     @Override public void run(){ 
     Utils.instantiateHelper(getBaseContext()); 
     mHelper.insertItem(item); } 
     }).start(); 
    } 




public class mService extends Service{ 
     public void insert some item in database(final Item item) // this method is called in the service at some time 
      (new Thread(){ 
      @Override public void run{ 
      Utils.instantiateHelper(getBaseContext()); 
      mHelper.insertItem(item); } 
     }).start(); 
    } 

现在,如果双方在服务和活动尝试一起插入项目。我经常会遇到这种情况,并发生错误。 为了避免这种情况我使用此解决方法:

我把插入操作在try块,失败我等待随机的时间,然后再试一次

public void insertSomeItemInDatabase(final Item item) 
    (new Thread(){ 
      @Override public void run(){ 
       int i=0; 
       Random rand=new Random(); 
       while(true){ 
        if(i>10) 
        return; 
        try{ 
        Utils.instantiateHelper(getBaseContext()); 
        mHelper.insertItem(item); 
        break; 
        }catch(Exception e){ 
         i++; 
          try{ 
           Thread.sleep(rand.nextInt(1000)); 
           }catch(Exception e){} 
         } 

         } 
      } 
      } 
     }).start(); 
    } 

我知道这是对最差方法同步但由于我太新鲜了java任何一个可以请解释如何在这种情况下使用​​。

谢谢

+0

为什么你的insertSomeItemInDatabase没有同步? – njzk2

+0

供参考:您的方法是网络协议中的常用方法。它有点类似于[Aloha协议](http://en.wikipedia.org/wiki/ALOHA_protocol#The_ALOHA_protocol)。如果你想坚持这种方法,你可能想申请[exponantial back off](http://en.wikipedia.org/wiki/Exponential_backoff)。 – amit

+0

我不太了解同步静态变量。一个代码片段和解释将是一个很好的帮助@ njzk2 –

回答

1

我认为所有您需要的是创造应用类

[1]这是在所有其他类中使用你已经采取的Util所有这些变量,可以被带入这个应用程序类。所以这些变量将可用于所有其他类。

[2]创建Singelton实例申请类别。只是谷歌关于它。

[3]同时创建DataBaseHelper的Singleton(如果可能并且可以应用),所以,单实例可以帮助你在每个地方。


应用程序类是Android中的全局类,因此您可以使用它来存储和访问所有Global-Data。例如:

public class AppData extends Application { 

    public static AppData appData; 

    public int currentUserId; // etc. 

    //Const. 
    public AppData() { 
     appData = this; 
    } 

    @Override 
    public void onCreate() { 
     super.onCreate(); 
     loginPreferences = getSharedPreferences(
      SPF_NAME, 0); 

     pathToSDCard = Environment.getExternalStorageDirectory().getAbsolutePath(); 
     System.out.println("Path : " + pathToSDCard); 
     //etc. 
    } 

// MOST IMP FOR GETTIN SINGELTON INSTANCE  <<<---<<<---<<<--- 
    public static AppData getAppData() { 
     return appData; 
    } 
} 

如何使用它,请参阅本

class ABC extends Activity { 
    AppData appData; 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.xyz); 

     appData = AppData.getAppData(); 
     ........... 
     ........... 

     appData.VARIABLE_NAME... 
    } 
} 

还有一件事。在AndroidMenifest中。xml

... 
    ... 
<application    // In Application Tag 
     android:name="PACKAGE_NAME.AppData" // << Add here class name in which you have extended Application 
     android:icon="@drawable/ic_launcher" 
    ... 
    ...