您如何考虑和预测这样的线程问题的输出? [英] How do you think through and predict the output of a threading question like this?

查看:77
本文介绍了您如何考虑和预测这样的线程问题的输出?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在为SCJP做准备,而多线程一直是我最不稳定的领域,主要是因为我不知道如何看待多线程代码并逐步学习.到目前为止,我的方法是用英语写下每个线程中可能发生的情况,并通过随机相交的线程来测试一些情况,这确实是一个断断续续且费时的方法.所以我想看看专业人士会怎么做.您是否愿意阅读下面的代码(这是给我带来麻烦的最新问题),并在确定可能的输出时写下您的想法(仅与代码有关的东西:).问题所带来的选择在最后.我要寻找的不是我拥有的解决方案,而是在考试中如何有效地找到解决方案.

是的,我知道这个问题没有确切的答案,依此类推.接受的投票投给了最清晰,最容易模仿的答案,好吧:)

谢谢大家!

问题:以下哪个答案是可能的输出?

public class Threads1 {

    int x = 0;

    class Runner implements Runnable {

        public void run() {
            int current = 0;
            for (int i = 0; i < 4; i++) {
                current = x;
                System.out.print(current + ", ");
                x = current + 2;
            }
        }
    }

    public static void main(String[] args) {
        new Threads1().go();
    }

    public void go() {
        Runnable r1 = new Runner();
        new Thread(r1).start();
        new Thread(r1).start();
    }
}

选择(选择所有适用选项):

A. 0、2、4、4、6、8、10、6,

B. 0,2,4,6,8,10,2,4,

C. 0、2、4、6、8、10、12、14,

D. 0、0、2、2、4、4、6、6、8、8、10、10、12、12、14、14

E. 0、2、4、6、8、10、12、14、0、2、4、6、8、10、12、14,

解决方案

A和C (假设问题是这些答案中的哪些是可能的输出?)

当然,难的部分不是在您找到可能的解决方案时.但是相反,它会认真研究您认为不可能的可能性,并试图说服自己您有充分的理由解释为什么不可能并且已经消除了解决您的理由的所有方法.

到目前为止,我的方法是用英语写下每个线程中可能发生的情况...

您需要弄清楚每个数字印在哪个线程上.以下是我能想到的最有效,最简洁的格式,它使您在尝试各种可能性时可以轻松划掉/擦除/覆盖.实现:

  • 一旦找到可能的答案继续.无论是在现实世界中是不可能的,还是可能存在其他可能(或不可能的)组合,都没有关系.只要您发现1种可能性,便是继续前进的全部条件.

  • 首先尝试最简单的方法,例如假设每个数字都为T1,直到您碰到一个不能为T1的数字,所以您填写T2,依此类推..希望您到最后都没有矛盾(或容易解决的矛盾).找到可能的组合后,继续前进.

  • 随意跳过以快速消除可能的对象,以便您专注于可能的不可能的对象.

这是我的草稿纸/工作表的最终编辑(附上我的心理注释):

A. 0, 2, 4, 4, 6, 8, 10, 6,
   1  1  1  2  2  2   2  1     <- possible threads that produced this output - possible solution

B. 0, 2, 4, 6, 8, 10, 2, 4,
   1  2  2  2  2   ?  1        <- to print second '2', T1 interrupted between L10/L11; 4 passes of T2 used up

C. 0, 2, 4, 6, 8, 10, 12, 14,
   1  1  1  1  2   2   2   2   <- possible solution - simplest solution (T2 waits until T1 is completely done) - doesn't matter that it isn't likely, just that is possible

D. 0, 0, 2, 2, 4, 4, 6, 6, 8, 8, 10, 10, 12, 12, 14, 14,
   1  2  1  2  1  2  1  2  1  2   ?    <- threads used up

E. 0, 2, 4, 6, 8, 10, 12, 14, 0, 2, 4, 6, 8, 10, 12, 14,
   1  1  1  1  2   2   2   2  ?   <- threads used up

注意:

http://download.oracle.com/javase/tutorial/essential/concurrency/atomic.html

  • 对于引用变量和大多数原始变量(除long和double以外的所有类型),读写是原子的.
  • ...

原子操作不能交错,因此可以使用它们而不必担心线程干扰.

I'm prepping for the SCJP, and multithreading has been my shakiest area, mostly because I don't know how to look at multithreading code and walk through it. So far my approach has been to write down in English what might be happening in each thread and testing a few cases with threads randomly intersecting each other, which is a really hit-and-miss and time-consuming approach. So I'd like to see how a pro would go about it. Would you be willing to read the code below (it's the latest question that's giving me trouble) and write down what goes through your head (code-related stuff only, please :) as you work out the possible outputs? The choices that come with the question are at the end. What I'm looking for isn't the solution, which I have, but how one arrives at the solution efficiently on the exam.

And yeah, I know this question doesn't have a precise answer, etc etc. Accepted vote goes to the answer that's clearest and easiest to emulate, okay :)

Thanks everyone!

Question: Which of these answers are possible outputs?

public class Threads1 {

    int x = 0;

    class Runner implements Runnable {

        public void run() {
            int current = 0;
            for (int i = 0; i < 4; i++) {
                current = x;
                System.out.print(current + ", ");
                x = current + 2;
            }
        }
    }

    public static void main(String[] args) {
        new Threads1().go();
    }

    public void go() {
        Runnable r1 = new Runner();
        new Thread(r1).start();
        new Thread(r1).start();
    }
}

Choices (choose all that apply):

A. 0, 2, 4, 4, 6, 8, 10, 6,

B. 0, 2, 4, 6, 8, 10, 2, 4,

C. 0, 2, 4, 6, 8, 10, 12, 14,

D. 0, 0, 2, 2, 4, 4, 6, 6, 8, 8, 10, 10, 12, 12, 14, 14,

E. 0, 2, 4, 6, 8, 10, 12, 14, 0, 2, 4, 6, 8, 10, 12, 14,

解决方案

A and C (assuming the question is Which of these answers are possible outputs?)

The hard part, of course, isn't when you find a possible solution. But rather, its to look hard at the ones that you think are not possible and try to convinced yourself that you've got a solid reason why its not possible and that you've eliminated all the ways to get around your reason.

So far my approach has been to write down in English what might be happening in each thread ...

You need to figure out which thread printed each number. Below is the most efficient, succinctness format I could think of represent that and make it easy to crossout/erase/write-over as you work through possibilities. Realize:

  • Once you find an possible answer move on. It doesn't matter if it isn't likely in the real world or that there may be other possible (or impossible) combinations. As long as you found 1 possibility, that's all you need to move on.

  • Try the simplest approach first, e.g. assume T1 for each number until you hit a number that couldn't be T1, so you fill in T2, and so on.. Hopefully, you get to the end with no contradiction (or contradictions that are easy to resolve). Once you've found a possible combination, move on.

  • Feel free to skip around to eliminate the possible ones quickly so you can focus on the likely impossible ones.

Here is the final edit of my scratch-paper/worksheet (appended with my mental annotations):

A. 0, 2, 4, 4, 6, 8, 10, 6,
   1  1  1  2  2  2   2  1     <- possible threads that produced this output - possible solution

B. 0, 2, 4, 6, 8, 10, 2, 4,
   1  2  2  2  2   ?  1        <- to print second '2', T1 interrupted between L10/L11; 4 passes of T2 used up

C. 0, 2, 4, 6, 8, 10, 12, 14,
   1  1  1  1  2   2   2   2   <- possible solution - simplest solution (T2 waits until T1 is completely done) - doesn't matter that it isn't likely, just that is possible

D. 0, 0, 2, 2, 4, 4, 6, 6, 8, 8, 10, 10, 12, 12, 14, 14,
   1  2  1  2  1  2  1  2  1  2   ?    <- threads used up

E. 0, 2, 4, 6, 8, 10, 12, 14, 0, 2, 4, 6, 8, 10, 12, 14,
   1  1  1  1  2   2   2   2  ?   <- threads used up

Note:

http://download.oracle.com/javase/tutorial/essential/concurrency/atomic.html

  • Reads and writes are atomic for reference variables and for most primitive variables (all types except long and double).
  • ...

Atomic actions cannot be interleaved, so they can be used without fear of thread interference.

这篇关于您如何考虑和预测这样的线程问题的输出?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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