java - java中的同步多线程

标签 java multithreading

我是自学Java,想了解多线程。我创建了一个包含作业的 MyThread 类来执行循环直到条件为真,然后打印有关它的信息。它包含静态字段 left,它在构造函数中递增并在作业完成时递减。 Flag 类“告诉”线程何时开始。 不幸的是,当所有线程都完成时,left 不等于零。我做了一些方法 synchronized 并且它变得更好但它仍然不完美。 我做错了什么?

import java.util.Random;

class Flag
{
    private boolean ok = false;
    synchronized boolean ok()
    {
        return ok;
    }
    synchronized void setOk(boolean ok)
    {
        this.ok = ok;
    }
}

class MyThread extends Thread
{
    static int left = 0;

    synchronized void add()
    {
        left++;
    }

    synchronized int remove()
    {
        return --left;
    }

    String name;
    Flag flag;
    Random rnd = new Random();
    public MyThread(String name, Flag flag)
    {
        this.name = name;
        this.flag = flag;
        add();
    }

    public void run()
    {
        while(!flag.ok());

        double rnd;
        long count = 0;
        do{
            count++;
            rnd = Math.random();
        } while(rnd > 0.00001);
        print(count);
    }

    synchronized void print(long count)
    {
        System.out.printf("%s %10d left: %3d%n", name, count, remove());
    }
}

public class Test
{
    public static void main(String... args) throws Exception
    {
        Flag flag = new Flag();
        for(int i=0; i<2000; i++){
            new MyThread(String.format("%04d",i),flag).start();
        }

        flag.setOk(true);
    }
}

最佳答案

由于静态变量上的对象同步导致意外结果。

我已经测试了你的代码,几乎没有改动。我将 Synchronized block 与 MyThread.class 一起使用,因为我需要同步 MyThread 中的静态变量。

void add() {
    synchronized (MyThread.class) {
        left++;
    }
}

int remove() {
    synchronized (MyThread.class) {
        return --left;
    }
}

每次打印预期结果。您还可以使用 AtomicInteger 变量。它用于原子递增计数器等应用程序。

关于java - java中的同步多线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15458658/

相关文章:

multithreading - 缺少OpenMP功能: Thread Priority

Python 使用 subprocess.Popen 关闭所有线程或进程

Python 全局变量不在线程中更新

java - 如何从非主键表的 hibernate 列表中选择数据,其中所有列的where子句数据都相同

java - 为什么 FileReader 无法读取第一行末尾以外的内容?

java - 使用 envers 跟踪收视率

multithreading - golang线程数误导

Java- 试图分配较弱的类权限

Java日期给我格式mm/dd/yyyy,其中jquery datepicker日期格式是dd/mm/yyyy

Javafx 任务/线程不启动