【问题标题】:Synchronized method in androidandroid中的同步方法
【发布时间】:2019-03-15 06:29:30
【问题描述】:

您可能认为这个问题与this 重复,但没有该问题的答案有助于我理解android 中的synchronized 方法。我在谷歌上搜索了很多以了解synchronized 方法,我找到了一些答案,但它们并没有帮助我完全理解Synchronized 方法,因为没有答案有任何完美的实际示例。

我试图通过在我的代码中实现 2 个synchronized 方法并同时执行它们来理解synchronized 方法,但我未能正确实现它们。所以,请用简单例子解释synchronized方法,这样我这样的人也可以简单快速地理解它。

更新

我不确定我是否朝着正确的方向前进,但我尝试了以下具有 2 个同步方法的代码。

synchronized void add() {
    counter++;
    Log.e("JK", String.valueOf(counter));
}

synchronized void minus() {
    counter--;
    Log.e("JK", String.valueOf(counter));
}

我已经使用下面的代码在两个不同的线程中调用了这个方法。

new Handler().postDelayed(new Runnable() {
                @Override
                public void run() {
                    synchronized (counter++) {
                        add();
                    }
                }
            },500);
            new Handler().postDelayed(new Runnable() {
                @Override
                public void run() {
                    minus();
                }
            },1000);

【问题讨论】:

  • 请将您的代码减少到最小可能的示例,以重现您的问题并发布它。您现在要求我们解释同步的整个概念,如果不做任何更改,它就有资格被关闭为“过于宽泛”。
  • 好的...让我发布我的代码。 @Torben
  • @Torben 请查看更新后的问题。
  • synchronized(counter++) {add();}的使用不正确,add方法已经同步,不需要放在runnable的同步块中。此外,计数器似乎是共享资源,您不希望同时从 2 个线程访问它。这意味着您应该从同步方法中更改它

标签: java android synchronized


【解决方案1】:

同步方法是一种一次只能由一个线程使用的方法。 其他线程将一直等待,直到该方法被释放。 您应该有充分的理由将方法声明为同步,因为这种方法会降低生产力。使用同步方法的经典案例是当多个线程使用相同的资源时,即改变某个对象的状态,并且需要确保一次只有一个线程执行它,否则会导致不一致。还要确保使同步方法尽可能小,理想情况下将其减少到仅包含可以操作公共资源的操作。

例如类 Reporter 有公共资源 fileWriter。它写入一些包含作者信息的消息。

class Reporter{
    private FileWriter fileWriter;
    public synchronized void addRecord(String author, String message) throws IOException {
        fileWriter.write("\n<<<<<<<<<<>>>>>>>>>>\n");
        fileWriter.write("Message written by:" + author + "\n");
        fileWriter.write("Message content:" + message);
    }

    public Reporter(FileWriter fileWriter) {
        this.fileWriter = fileWriter;
    }
}

假设您从 2 个不同的线程运行此代码:

Reporter reporter = new Reporter("path/report");
...
Thread thread = new Thread(){
    public void run(){
      reporter.addRecord("John", "Hi");
    }
  }
 thread.start();
Thread thread2 = new Thread(){
    public void run(){
      reporter.addRecord("Bill", "Hello");
    }
  }
 thread2.start();

同步方法的结果是这样的:

<<<<<<<<<<>>>>>>>>>>
Message written by:John
Message content:Hi
<<<<<<<<<<>>>>>>>>>>
Message written by:Bill
Message content:Hello

如果方法不同步,多个线程可能同时写入文件,这会导致文件中出现不可预知的顺序,如下所示:

<<<<<<<<<<>>>>>>>>>>
<<<<<<<<<<>>>>>>>>>>
Message written by:John
Message written by:Bill
Message content:Hello
Message content:Hi

【讨论】:

  • 感谢您的宝贵回答,但如果您提供任何示例会更好。
  • @Jaydip 示例添加
  • 是的,你是对的,但我怎样才能生成这两种情况的输出?
  • 使用运行同步方法的代码更新答案,以查看使用和不使用同步声明运行相同代码的差异
【解决方案2】:

同步方法是一种一次只能由一个线程使用的方法。其他线程将一直等待,直到该方法被释放。您应该只有正当理由将方法声明为同步,因为这种方法会降低生产力和性能。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-08-29
    • 2011-01-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-08
    相关资源
    最近更新 更多