【问题标题】:Why do we use synchronized keyword while our aim of using multi-threading is parallel computing?为什么我们使用 synchronized 关键字,而我们使用多线程的目的是并行计算?
【发布时间】:2022-10-02 00:51:00
【问题描述】:

我们使用多线程的目标是并行计算,但这里我们使用 synchronized 关键字来允许一次单个线程。那么我们如何实现并行计算呢?如果可能,请提供一些相关的可理解的编码示例。

class Counter {
    int count;
    
    public synchronized void increment() {
        count++;
    }
}

public class SyncDemo {
    public static void main(String[] args) throws Exception {
        Counter c = new Counter();
        
        Thread t1 = new Thread(new Runnable() {
           public void run() {
               for (int i=1; i<=1000; i++) {
                   c.increment();
               }
           } 
        });
        
        Thread t2 = new Thread(new Runnable() {
           public void run() {
               for (int i=1; i<=1000; i++) {
                   c.increment();
               }
           } 
        });
        
        t1.start();
        t2.start();
        
        t1.join();
        t2.join();
        
        System.out.println(\"Count: \" + c.count);
    }
}

注意:此代码来自 YouTube 视频。

  • 正如您已正确识别的那样,不在此示例中。你刚刚选择了一个不好的例子来展示并行计算。您不能并行增加单个计数器并期望得到正确的结果,但您可以并行执行其他操作!
  • 为什么这个关于 Java 的问题被标记为 C#?当您的问题与他们无关时,不要试图诱骗他们查看您的问题。仅应用实际相关的标签。
  • 这段代码不是并行计算的一个很好的例子,但它一个安全并发的例子。
  • @jmcilhinney。谢谢你的警告。这个问题不是关于 java 或 C#,而是关于多线程和同步概念。我想,在 C# 中,这个概念也存在。
  • 您特别提到了 synchronized 关键字,它存在于 Java 中,但不存在于 C# 中。如果您想谈论更一般的概念,则不应询问有关特定语言关键字的问题。

标签: java multithreading synchronization


【解决方案1】:

您的两个线程改变了一个共享状态,即计数器。由于在 Java 中递增不是原子操作,count++ 就是所谓的临界区必须保护它一次不能被多个线程输入。为此,您的代码在方法increment() 上使用synchronized 关键字。

如果您想并行计数,请不要共享计数器。

给每个线程一个自己的 Counter 实例,那么 increment() 将永远不会被一个 Counter 实例上的多个线程一次调用。不再需要线程同步那里.

这并不意味着您根本不需要协调线程:因为您要输出总计数,这只能在所有线程都完成工作时完成。一种方法是像 main 方法一样加入线程。之后,您可以输出各个计数的总和。

【讨论】:

    最近更新 更多