java - 使用 System.out.println(Thread.currentThread().getName() + ""+count);导致同步

标签 java multithreading synchronization synchronized

我在 java 中学习多线程,在教程中,它说删除同步会使程序出现错误,而且确实如此,所以我只是试验并写了一个打印行 System.out.println(Thread.currentThread ().getName() + ""+count); 并删除了同步词,即使这样程序也能正常工作。但是,如果仅删除同步字并且未添加 printline(System.out.println(Thread.currentThread().getName() + ""+count);) 则程序存在错误广告.

我无法理解添加打印行如何使其同步。

public class intro implements Runnable {

    int n=10000; 
    private int count = 0; 

    public int getCount() { return count; }

    public synchronized void incrSync() { count++;  }

    public void run () {
        for (int i=0; i<n; i++) {
            incrSync();
            //System.out.println(Thread.currentThread().getName() + "  " +count);       
        } 
        } 


    public static void main(String [] args) {

        intro mtc = new intro();
        Thread t1 = new Thread(mtc);
        Thread t2 = new Thread(mtc);
        t1.start();
        t2.start();
        try {
            t1.join();

            t2.join();

        } catch (InterruptedException ie) {
        System.out.println(ie);
        ie.printStackTrace();
    }
    System.out.println("count = "+ mtc.getCount());
}
}

最佳答案

当多个线程同时尝试访问同一字段时,线程之间会发生同步问题。

如果不打印,run 方法将处于紧密循环中,几乎连续不断地访问计数器。让多个线程在没有同步的情况下执行此操作很可能会导致错误。

通过添加打印,您正在改变循环,使其大部分(几乎所有)时间都用于打印,只是偶尔增加计数。这不太可能引起争用。

代码在打印方面仍然存在问题,唯一的区别是争用发生的频率要低得多,而您仅对 1000 循环进行的测试不足以证明该问题。在线程发生冲突之前,您可能必须运行它几年。

这是一个经典的演示,说明为什么线程问题如此难以查找和修复。该循环(带有它的 print 语句)可以在多个线程上运行多年而不会发生争用,但是如果线程之间只发生一次冲突,那么代码就会中断。想象一下,这发生在心脏起搏器、卫星或核电站中!

关于java - 使用 System.out.println(Thread.currentThread().getName() + ""+count);导致同步,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44173884/

相关文章:

java - 可变数量的线程/声明 ExecutorService

c++ - 监控一个线程的状态

c# - 如何在多线程服务器上使用字典

java - 基本数据记录器的实现

emacs - 如何同步Emacs软件包和设置?

java - 查找大范围内奇数位素数的算法

java - 通用方法的 JUnit 测试用例

java - 当另一个线程正在更新数据库时,如何阻止查询线程?

java - Spring Boot SPA URL 重写

java - 使用数组列表并出现错误