java中的线程和共享计数器 [英] Threads and shared counters in java

查看:174
本文介绍了java中的线程和共享计数器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在uni进行了这个练习:

I got this exercise at uni:

编写一个声明共享整数计数器然后创建两个线程的程序,其中一个尝试将计数器递增1000次而另一个尝试将计数器减少1000次。当每个线程完成循环时,它应该打印出计数器的最终值。 (提示:您需要定义一个Counter类。为什么?)您认为输出应该是什么?程序是否按预期工作?尝试重复运行程序以查看是否总能得到相同的结果。

Write a program that declares a shared integer counter and then creates two threads, one of which attempts to increment the counter 1000 times and the other attempts to decrement the counter 1000 times. When each thread has finished looping, it should print out the final value of the counter. (Hint: You will need to define a Counter class. Why?) What do you think the output should be? Did the program work as you expected? Try running the program repeatedly to see if you always get the same result.

我运行程序期望最终结果为零,但它实际上输出一个不同的数字每次0和1000。谁能告诉我为什么?谢谢。

I ran the program expecting the final result to be zero, but it actually outputs a different number between 0 and 1000 each time. Can anyone tell me why? Thanks.

public class Counter
{
    private int val;

    public Counter()
    {
        val = 0;
    }

    public void increment()
    {
        val = val + 1;
    }

    public void decrement()
    {
        val = val - 1;
    }

    public int getVal()
    {
        return val;
    }
}

public class IncThread extends Thread
{
    private static final int MAX = 1000;
    private Counter myCounter;

    public IncThread(Counter c)
    {
        myCounter = c;
    }   

    public void run()
    {
        for (int i = 0; i < MAX; i++)
        {
            myCounter.increment();
        }
    }

}

public class DecThread extends Thread
{
    private static final int MAX = 1000;
    private Counter myCounter;

    public DecThread(Counter c)
    {
        myCounter = c;
    }

    public void run()
    {
        for (int i = 0; i < MAX; i++)
        {
            myCounter.decrement();
        }
    }
}

public class Main
{
    public static void main(String[] args)
    {
        Counter c = new Counter();

        Thread inc = new IncThread(c);
        Thread dec = new DecThread(c);

        inc.start();
        dec.start();

        System.out.println(c.getVal());

    }
}


推荐答案

在最低级别,您的代码可能归结为:

At the lowest level, your code probably boils down to something like:

Thread1                Thread2
-------                -------
do 1000 times          do 1000 times          
    get reg from [a]       get reg from [a]   
    reg = reg + 1          reg = reg - 1
    store reg to [a]       store reg to [a]

因此和线程可以在执行的任何时刻停止并启动,你可以这样做:

Because of that and the fact that threads can be stopped and started at any point of their execution, you have the possibility of this:

Thread1                Thread2
-------                -------
get reg from [a] (0)
                       get reg from [a] (0)
reg = reg + 1 (1)
                       reg = reg - 1 (-1)
                       store reg to [a] (-1)
store reg to [a] (1)

你可以看到,虽然两个线程都完成了千个周期中的一个,你希望计数为零,实际上是一个。

You can see that, although both threads have finished exactly one of the thousand cycles and you expect the count to be zero, it is actually one.

在执行线程之间共享变量时,你需要确保读取,写入和更新是原子的(有例外但很少见)。

When sharing variables among threads of execution, you need to ensure that reads, writes and updates are atomic (there are exceptions but they're rare).

为此,您应该查看环境中提供的各种操作仅用于此目的(例如语言中的同步功能,互斥量(互斥信号量)或原子变量。

To do this, you should look into the various operations provided in your environment for just this purpose (such as synchronisation features in the language, mutexes (mutual exclusion semaphores) or atomic variables.

这篇关于java中的线程和共享计数器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆