java ,Properly using Static variables to prevent deadlock - Synchronizing

二次信任 提交于 2019-12-24 11:24:29

问题


I am new to android programming and 've not thoroughly studied java before . I am really confused on how to use synchronized to ensure thread safety on static variables :

I usually create a class named Utils which has some static functions which are most of the time needed by all my other classes. Is this the correct way of keeping repetitive code out of my classes.

I always suffer from a problem with using Databases. When I create sqliteHelper class for certain Database and try to manage that database from say an Activity and a Background service , I usually get into trouble. If I use local objects of helper class , I am maximum prone to getting into deadlocking of database when both the helper objects try to acquire write lock together.

For getting out of this trouble , I create a static instance of the helper class in my utils class. Now for performing any operation on database my activity and my service do the following thing :

   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();
     }

Now what if both the service and the activity try to insert the item together. I oftentimes get into this situation and an error occurs . To avoid this I use this workaround :

I put the insert operation in a try block and on failure I wait for random time and try again

    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();
     }

I know this is the Worst method of synchronizing but since I am so new to java can any one please explain how to use synchronized in this Scenario .

Thank You


回答1:


I think all your need is to create Application Class

[1] All those variables you have taken in Util, which are used in about all other class, can be taken in this Application class. So these variables will be available to all other classes.

[2] Create Singelton instance of Appliction class. Just Google about it.

[3] Also create Singleton of DataBaseHelper(if possible and can apply), so, single instance helps you every where.


Application Class is Global class in android, so you can use it to store and access all Global-Data. e.g. :

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;
    }
}

HOW TO USE IT, SEE THIS

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...
    }
}

One thing more. In 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"
    ...
    ...


来源:https://stackoverflow.com/questions/12744094/java-properly-using-static-variables-to-prevent-deadlock-synchronizing

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!