简体   繁体   English

这个Java线程程序有什么问题

[英]what is wrong with this java thread program

I am trying to figure out what is wrong with this thread program in java. 我试图弄清楚java中的该线程程序出了什么问题。 Can anyone shed some light? 谁能阐明一些想法? Here is the code: 这是代码:

public class Z {
    private Account account = new Account();
    private Thread[] thread = new Thread[100];

    public static void main(String[] args) {
        Z test = new Z();
        System.out.println("What is balance ? " + test.account.getBalance());
    }

    public Z() {
        ThreadGroup g = new ThreadGroup("group");
        boolean done = false;

        // Create and launch 100 threads
        for (int i = 0; i < 100; i++) {
            thread[i] = new Thread(g, new AddAPennyThread(), "t" + i);
            thread[i].start();
            System.out.println("depositor: " + thread[i].getName());
        }
        // Check if all the threads are finished
        while (!done)
            if (g.activeCount() == 0)
                done = true;
    }

    // A thread for adding a penny to the account
    class AddAPennyThread extends Thread {
        public void run() {
            account.deposit(1);
        }
    }

    // An inner class for account
    class Account {
        private int balance = 0;

        public int getBalance() {
            return balance;
        }

        public void deposit(int amount) {
            int newBalance = balance + amount;
            balance = newBalance;
        }
    }
}

It compiles and runs fine. 它可以编译并运行良好。 It was a test question I missed and wnated to know what is actually wrong with it. 我错过了这个测试问题,并想知道它到底有什么问题。 Thanks! 谢谢!

There is not a single bit dedicated to synchronization of 100 threads all working on exactly one (1!!!) piece of data. 没有一个专用于100个线程的同步,而所有线程都只处理一个 (1 !!!)数据。

Anything can happen. 什么都可能发生。 "Anything" includes that the code as it is works most of the time due some "coincidences": “任何内容”都包括由于某些“巧合”而使代码大部分时间都可以使用的情况:

  • The task at hand is quite small. 手头的任务很小。 (only an add) (仅添加)
  • The tasks are created and immediately started. 任务已创建并立即启动。
  • There is a small delay between two "create+start" pair: the System.out.println . 在两个“ create + start”对之间有一个小的延迟: System.out.println

This adds up to: This might work in most test-runs. 这就增加了:在大多数试运行,这可能工作。 But it is an incorrect and non-deterministic program. 但这是一个不正确且不确定的程序。

[Tread1] int newBalance = balance + amount;
[Tread2] int newBalance = balance + amount;
[Tread1] balance = newBalance;
[Tread2] balance = newBalance;

public synchronized void deposit(int amount)

balance should be a private volatile int (so that Java knows to never cache it - its value is liable to change between different thread accesses without the next thread knowing) and make Account#deposit(int amount) a public synchronized void (so that Java makes the method body a critical region and prevents simultaneous access of any of the objects it touches, ensuring the integrity of the value of balance ). balance应该是一个private volatile int (这样,Java知道永远不会缓存它-它的值很容易在不同的线程访问之间进行更改,而无需下一个线程知道),并使Account#deposit(int amount)成为一个public synchronized void (这样,Java使方法主体成为关键区域,并防止同时访问它所接触的任何对象,从而确保balance值的完整性。

Additionally, instantiating 100 threads yourself with new introduces a lot of overhead - though I appreciate this is just a toy example, a more efficient way to do this would be to use a Java thread pool . 此外,用new实例化100个线程会带来很多开销-尽管我欣赏这只是一个玩具示例,但更有效的方法是使用Java线程池

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM