我正在尝试使用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();
}
}
代码未正确同步,这就是问题所在。
您的代码中允许以下执行顺序:
chk == true
,将其设置为false
并进入if
块。chk == false
,将其设置为true
并进入if
块。现在,您在自己的if
块中都有2个线程,准备执行以下操作:
incrementAndGet()
数字因此,您绝对无法控制将要发生的事情。
incrementAndGet()
,因此可以先打印线程“ Odd”,首先打印奇数,然后再打印偶数。chk
为true
打印,所有这些都在第二个线程有机会打印之前)。如您所见,要获得所需的结果,必须原子完成以下操作:
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。。。我该怎么处理这些线呢?