美文网首页
Android如何跨进程同步

Android如何跨进程同步

作者: 笔记本65 | 来源:发表于2022-04-20 10:16 被阅读0次

两个进程要进行同步,如果用IPC机制通信来同步,那么就会遇到一个问题,那就是这两个进程必须都已经启动才可以,如果遇到一个进程启动,但是另外一个进程不知道什么时候启动,这个办法就很难行得通了。

这时候就可以用到Android系统根据java提供的FileLock

1.FileLock是线程安全的

2.FileLock适用于进程间文件读写控制,不适用于同一进程的不同线程

3.分为共享锁和独占锁,共享锁允许其他进程同样获取共享锁,独占锁不允许其他进程获得锁。

4.有两种方式获得文件锁,FileChannel的lock和tryLock,用lock会阻塞当前线程,直到获取到锁,用tryLock会尝试获取,如果获取失败则返回null,不会阻塞线程。

5.FileLock释放的条件是:自己调用release/close或者所使用的FileChannel调用close或者是JVM终止运行。

6.文件锁的效果是与操作系统相关的。一些系统中文件锁是强制性的,当Java的某进程获得文件锁后,操作系统将保证其它进程无法对文件做操作了。而另一些操作系统的文件锁是询问式的(advisory),意思是说要想拥有进程互斥的效果,其它的进程也必须也按照API所规定的那样来申请或者检测文件锁,不然将起不到进程互斥的功能。所以文档里建议将所有系统都当做是询问式系统来处理,这样程序更加安全也更容易移植。

我们这里用的就是独占锁。

public class FileLockTest {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        FileChannel channel = null;
        FileLock lock = null;
        try {
            FileOutputStream raf = new FileOutputStream("logfile.txt");
            channel = raf.getChannel();
            lock = channel.lock();
            Thread.sleep(10000);
            lock.close();
            System.err.println(System.currentTimeMillis() + "  release lock");
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

}

这个是先运行的获取锁的类,获取锁后持有10s后释放。

public class LockTest2 {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        new Thread(new Runnable() {

            @Override
            public void run() {
                // TODO Auto-generated method stub
                FileChannel channel = null;
                FileLock lock = null;
                try {
                    FileOutputStream raf = new FileOutputStream("logfile.txt");
                    channel = raf.getChannel();
                    lock = channel.lock();
                    if (lock.isValid()) {
                        //any thing you want
                        System.out.println(System.currentTimeMillis() + "  ok");
                    } else {
                        System.out.println("no ok");
                    }

                } catch (FileNotFoundException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }).start();

    }

}

这个类是在第一个类运行后再运行的类,此时该进程会一直等到FileLockTest释放锁后才能获得锁然后继续运行。我们可以在获得锁之后do any thing you want,从而实现进程间同步。

多次运行后可能有人会发现有时候先打印获得锁后打印释放锁,其实是这样的,这是两个进程,一个进程释放锁之后另外一个进程才可能获得锁,但是两个进程的打印时间的执行不是同步的,所以不一定是先打印释放锁,只要时间基本一致即可(本人多次运行时间差小于2ms)。

通过这两个类的分别运行,可以看到即使不是都启动完成,一样可以跨进程同步。

相关文章

网友评论

      本文标题:Android如何跨进程同步

      本文链接:https://www.haomeiwen.com/subject/emtvertx.html