当前位置: 首页 > 面试题库 >

java:使用2个线程打印奇数

万楷
2023-03-14
问题内容

我正在尝试使用2个不同的线程交替打印奇数和偶数。我能够使用等待,通知和同步块来实现它,但是现在我想评估是否可以不使用等待,通知和同步来实现它。

以下是我拥有的代码,但无法正常工作:

public class OddEvenUsingAtomic {

AtomicInteger nm = new AtomicInteger(0);
AtomicBoolean chk = new AtomicBoolean(true);

public static void main(String args[]) {
    final OddEvenUsingAtomic pc = new OddEvenUsingAtomic();

    new Thread(new Runnable() {

        @Override
        public void run() {
            while (true) {

                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }

                if (pc.chk.compareAndSet(true, false)) {

                    System.out.println("Odd: " + pc.nm.incrementAndGet());
                }
            }

        }

    }).start();

    new Thread(new Runnable() {

        @Override
        public void run() {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            while (true) {
                if (pc.chk.compareAndSet(false, true)) {

                    System.out.println("Even: " + pc.nm.incrementAndGet());
                }
            }

        }

    }).start();
}

}

有任何想法吗?

根据Bruno的建议,我创建了另一个版本,该版本似乎效果更好:

import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;

public class OddEvenUsingAtomic {

    AtomicInteger nm = new AtomicInteger(0);
    AtomicBoolean chk = new AtomicBoolean(true);

    public static void main(String args[]) {
        final OddEvenUsingAtomic pc = new OddEvenUsingAtomic();

        new Thread(new Runnable() {

            @Override
            public void run() {
                while (true) {

                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }

                    if (pc.chk.get() == Boolean.TRUE) {

                        System.out.println("Odd: " + pc.nm.incrementAndGet());
                        pc.chk.compareAndSet(true, false);
                    }
                }

            }

        }).start();

        new Thread(new Runnable() {

            @Override
            public void run() {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                while (true) {
                    if (pc.chk.get() == Boolean.FALSE) {

                        System.out.println("Even: " + pc.nm.incrementAndGet());
                        pc.chk.compareAndSet(false, true);
                    }
                }

            }

        }).start();
    }
}

问题答案:

代码未正确同步,这就是问题所在。

您的代码中允许以下执行顺序:

  1. 第一个线程看到chk == true,将其设置为false并进入if块。
  2. 第二个线程看到chk == false,将其设置为true并进入if块。

现在,您在自己的if块中都有2个线程,准备执行以下操作:

  1. incrementAndGet() 数字
  2. 打印它。

因此,您绝对无法控制将要发生的事情。

  • 您可以调用任何线程incrementAndGet(),因此可以先打印线程“ Odd”,首先打印奇数,然后再打印偶数。
  • 您可以让第一个线程循环打印数字,看看条件是否再次满足(因为第二个线程已再次设置chktrue打印,所有这些都在第二个线程有机会打印之前)。

如您所见,要获得所需的结果,必须原子完成以下操作:

  • compareAndSet() 布尔值
  • incrementAndGet() 数字
  • 打印它

如果这3个操作不是原子操作,则可以安排线程以任何可能的顺序运行这些操作,而您无法控制输出。实现此目的的最简单方法是使用同步块:

public static void main(final String... args) {
  final Object o = new Object();
  // ... thread 1 ...
    synchronized(o) {
      if (boolean is in the expected state) { change boolean, get number, increment, print }
    }
  // ... thread 2 ...
    synchronized(o) {
      if (boolean is in the expected state) { change boolean, get number, increment, print }
    }
}


 类似资料:
  • 问题内容: 使用线程进行奇数打印,创建一个线程类,两个线程实例。 一个将打印奇数,而另一个将打印偶数。 我做了以下编码。但这涉及到死锁状态。有人可以解释一下原因吗? 输出: 奇数1偶数2 然后陷入僵局!!!!!! 谢谢你的帮助。 问题答案: 您正在等待并通知其他对象( 监视器 )。 这个想法是,你在做和做的时候可以打电话等待一个人做。 将您的方法更改为类似 和方法类似。 然后为提供一个对象: 输出

  • 有两个线程,一个是打印偶数,另一个是打印奇数。在下面自定义锁的帮助下,我想按顺序打印数字。问题出在打印一些数字后(显示的数字顺序正确。)线程越来越死机。我花了一个多小时还是找不到问题,对我来说一切都很好。

  • 我是多线程的新手,我有一个问题,要在Java中使用10个线程打印1到100,并使用以下约束。 > 线程 应打印: 1, 11, 21, 31, ...91 < code>t2应打印: 2, 12, 22, 32, ... 92 同样地 < code>t10应打印: 10, 20, 30, ... 100 最终输出应为: 1 2 3 ..100 我已经尝试过了,但它在所有10个线程中都抛出了以下异常

  • 问题内容: 在我的代码中,我使用整数乘以100作为小数(0.1为10等)。您能帮我格式化输出以显示为十进制吗? 问题答案:

  • 我试图实现这一点:第一个线程打印1,第二个线程打印2,第三个线程打印3,第一个线程打印4等等: 我做到了这一点,并发挥了作用: 输出是这样的: 它达到了目的,但是如果我有两个线程要打印,那么我必须使用更多的如果条件。 任何人都可以建议以更好的形式编写这段代码,以更干净的方式完成任务,这样如果添加更多线程,它就可以扩展。

  • 这个问题是在电子艺术采访中提出的。 有三条线。第一个线程打印1到10个数字。第二个线程打印从11到20的数字。第三条线从21到30。现在这三个线程都在运行。然而,数字是按不规则的顺序打印的,如1、11、2、21、12等。 如果我想让数字按排序顺序打印,比如1,2。。。我该怎么处理这些线呢?