

Androidアプリ間で排他ロックを実現するために、FileLock、FileChannelクラスを利用していますが、以下のように複数アプリで同時にロックを獲得できる事象が発生しています。  
原因を教えて頂けないでしょうか。(環境はAndroid 5.0.1)

[code]

    public class MainActivity extends AppCompatActivity {
    
        private static final String TAG = "TEST1";
        private static final String fileName = Environment.getExternalStorageDirectory().getPath() + "/testFile";
        private FileLock mFileLock;
    
        private Button lockBt, releaseBt;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            lockBt = (Button) findViewById(R.id.lock_btn);
            releaseBt = (Button) findViewById(R.id.release_btn);
    
            lockBt.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    while(true){
                        if(lock()){
                            break;
                        }
    
                        try{Thread.sleep(1000);}catch (InterruptedException e){};
                    }
                }
            });
    
            releaseBt.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    release();
                }
            });
    
        }
    
        public boolean lock(){
            if(mFileLock != null){
                Log.d(TAG, "[lock]mFileLock is already locked.");
                return true;
            }
    
            FileLock fileLock = null;
            try{
                FileOutputStream fos = new FileOutputStream(new File(fileName));
                FileChannel fileChannel = fos.getChannel();
                fileLock = fileChannel.tryLock(0L, Long.MAX_VALUE, false);
            }catch(Exception e){
                Log.e(TAG, e.toString());
            }
    
            if(fileLock == null){
                Log.e(TAG, "[lock]file lock failed.");
                return false;
            }
    
            Log.i(TAG, "[lock]file lock success.");
            mFileLock = fileLock;
            return true;
        }
    
        public void release(){
            if(mFileLock == null){
                Log.i(TAG,"[release]mFileLock is null.");
                return;
            }
            try{
                mFileLock.release();
                File file = new File(fileName);
                if(file.exists()) file.delete();
            }catch(Exception e){
                Log.e(TAG, e.toString());
            }
            Log.i(TAG,"[release]lock released.");
            mFileLock = null;
        }
    }
    
[/code]

実行結果(logcat)

[code]

    07-19 15:24:36.790 12740-12740/test.test2 E/TEST2: java.io.IOException: fcntl failed: EAGAIN (Try again)
    07-19 15:24:36.790 12740-12740/test.test2 E/TEST2: [lock]file lock failed.
    07-19 15:24:37.842 12740-12740/test.test2 E/TEST2: java.io.IOException: fcntl failed: EAGAIN (Try again)
    07-19 15:24:37.842 12740-12740/test.test2 E/TEST2: [lock]file lock failed.
    07-19 15:24:38.015 12692-12692/test.test1 I/TEST1: [release]lock released.
    07-19 15:24:38.857 12740-12740/test.test2 I/TEST2: [lock]file lock success.
    07-19 15:24:40.922 12692-12692/test.test1 I/TEST1: [lock]file lock success.
    
[/code]


CC BY-SA 4.0
2018-07-19T14:12:34.203
46730
2022-12-30T17:08:30.970
27404
question
android
Androidでのファイルロックが正常に動作しない


きちんとソースを見ているわけではありませんので、別に原因があるかもしれませんが、一般にファイルによるロック方式ではうまくいかないことがあります。

【原因(と思われるもの)】  
ファイルの存在有無によってロックをかける方式はタイミング(※)によって多重ロックがかかる可能性があります。  
※ ファイルが存在しないことを確認してからファイルを生成するまでの間

【対処】  
ディレクトリの存在有無で排他を管理する。  
ロック用のディレクトリを作成し、正常に作成できればロック成立、作成できなければ他がロック済み。


CC BY-SA 4.0
2019-09-13T23:46:41.747
59051
2019-09-13T23:57:25.203
2019-09-13T23:57:25.203
35558
35558
46730
answer