使用Thread.yield()时,这三个线程不会轮流使用吗? [英] These three threads don't take turns when using Thread.yield()?

查看:163
本文介绍了使用Thread.yield()时,这三个线程不会轮流使用吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为了练习生锈的Java,我想尝试一个简单的多线程共享数据示例,但遇到了让我感到惊讶的事情.

In an effort to practice my rusty Java, I wanted to try a simple multi-threaded shared data example and I came across something that surprised me.

基本上,我们在三个线程之间有一个共享的AtomicInteger计数器,每个线程轮流递增并打印该计数器.

Basically we have a shared AtomicInteger counter between three threads that each take turns incrementing and printing the counter.

AtomicInteger counter = new AtomicInteger(0);

CounterThread ct1 = new CounterThread(counter, "A");
CounterThread ct2 = new CounterThread(counter, "B");
CounterThread ct3 = new CounterThread(counter, "C");

ct1.start();
ct2.start();
ct3.start();

CounterThread

public class CounterThread extends Thread
{   
    private AtomicInteger _count;
    private String _id;

    public CounterThread(AtomicInteger count, String id)
    {
        _count = count;
        _id = id;
    }

    public void run()
    {
        while(_count.get() < 1000)
        {
            System.out.println(_id + ": " + _count.incrementAndGet());
            Thread.yield();
        }
    }
}

我希望当每个线程执行Thread.yield()时,它将像这样将执行权交给另一个线程来递增_count:

I expected that when each thread executed Thread.yield(), that it would give over execution to another thread to increment _count like this:

A: 1
B: 2
C: 3
A: 4
...

相反,我得到了输出,其中A将使_count递增100次,然后将其传递给B.有时所有三个线程都会连续轮换,但有时一个线程会以几个增量占主导地位.

Instead, I got output where A would increment _count 100 times, then pass it off to B. Sometimes all three threads would take turns consistently, but sometimes one thread would dominate for several increments.

为什么Thread.yield()并不总是将处理移交给另一个线程?

Why doesn't Thread.yield() always yield processing over to another thread?

推荐答案

我希望当每个线程执行Thread.yield()时,它将把执行权交给另一个线程来像这样递增_count:

I expected that when each thread executed Thread.yield(), that it would give over execution to another thread to increment _count like this:

在旋转的线程应用程序中,很难预测输出.要获得完美的A:1 B:2 C:3 ...类型输出,您将不得不对锁和东西做很多工作.

In threaded applications that are spinning, predicting the output is extremely hard. You would have to do a lot of work with locks and stuff to get perfect A:1 B:2 C:3 ... type output.

问题在于,一切都是竞争条件,由于硬件,竞争条件,时间分段随机性和其他因素而无法预测.例如,当第一个线程启动时,在下一个线程启动之前,它可能运行了几毫秒. yield()不会有人.另外,即使产生了结果,也许您使用的是4处理器,所以根本没有理由暂停任何其他线程.

The problem is that everything is a race condition and unpredictable due to hardware, race-conditions, time-slicing randomness, and other factors. For example, when the first thread starts, it may run for a couple of millis before the next thread starts. There would be no one to yield() to. Also, even if it yields, maybe you are on a 4 processor box so there is no reason to pause any other threads at all.

相反,我得到的输出是A会递增_count 100次,然后将其传递给B.有时所有三个线程会一致地轮流执行,但是有时一个线程会以几个增量为主.

Instead, I got output where A would increment _count 100 times, then pass it off to B. Sometimes all three threads would take turns consistently, but sometimes one thread would dominate for several increments.

通常,在这种旋转循环中,您会看到单个线程在获取时间片时突然爆发. System.out.println(...)synchronized也会影响时序,这也使它感到困惑.如果未执行同步操作,则会看到更多的突发输出.

Right, in general with this spinning loops, you see bursts of output from a single thread as it gets time slices. This is also confused by the fact that System.out.println(...) is synchronized which affects the timing as well. If it was not doing a synchronized operation, you would see even more bursty output.

为什么Thread.yield()不会总是将处理移交给另一个线程?

Why doesn't Thread.yield() always yield processing over to another thread?

我很少使用Thread.yield().充其量只是对调度程序的提示,在某些体系结构上可能会被忽略.它暂停"线程的想法非常容易引起误解.可能会导致线程被放回运行队列的末尾,但是不能保证有任何线程在等待,因此它可能像删除了产量那样继续运行.

I very rarely use Thread.yield(). It is a hint to the scheduler at best and probably is ignored on some architectures. The idea that it "pauses" the thread is very misleading. It may cause the thread to be put back to the end of the run queue but there is no guarantee that there are any threads waiting so it may keep running as if the yield were removed.

在此处查看我的答案以获取更多信息:在多线程中不需要的输出

See my answer here for more info : unwanted output in multithreading

这篇关于使用Thread.yield()时,这三个线程不会轮流使用吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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