我有两个java线程。其中一个打印偶数,其他打印奇数。我需要按自然顺序打印数字。是否可以将两个线程同步到仅使用原始整数,如下所示? 节点:原始赋值在jvm中的java中是原子的。
public class NaturalNumber{
volatile int ai = 0;
public static void main(String str[]){
final NaturalNumber nn = new NaturalNumber();
Thread even = new Thread(new Runnable(){
int i=0;
public void run(){
//int i=0;
while(i<=200){
if(nn.ai ==0){
System.out.println(i);
i=i+2;
nn.ai =1 ;
}
}
}
});
Thread odd = new Thread( new Runnable(){
int i=1;
public void run(){
//int i=1;
while(i<=200){
if(nn.ai ==1) {
System.out.println(i);
i=i+2;
nn.ai =0 ;
}
}
}
});
odd.start();
even.start();
}
}
答案 0 :(得分:1)
这是如何使用锁定和同步来实现它,我认为这不容易出错。
public class NaturalNumber{
private boolean printEven = true;
private Object lock = new Object();
public NaturalNumber()
{
new Thread(()->even()).start();
new Thread(()->odd()).start();
}
private void even()
{
int i = 0;
while(i<=200)
{
synchronized (lock)
{
if(printEven)
{
System.out.println(i);
i += 2;
lock.notify();
printEven = false;
}
else //flag says next odd is to be printed, so wait until it has
{
try
{
lock.wait();
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
}
}
private void odd()
{
int i = 1;
while(i<=200)
{
synchronized (lock)
{
if(!printEven)
{
System.out.println(i);
i += 2;
lock.notify();
printEven = true;
}
else //flag says next even is to be printed, so wait until it has
{
try
{
lock.wait();
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
}
}
public static void main(String str[]){
new NaturalNumber();
}
}
答案 1 :(得分:0)
这似乎有效,它不仅保持对打印和评估代码的访问同步,而且防止同一个线程获得锁定两次(通过什么都不做)。
class NaturalNumber
{
private static boolean nextIsOdd = false;
public static void main(String str[])
{
Thread even = new Thread(new Runnable()
{
public void run() {
int i = 0;
while(i<=200) {
synchronized(this) {
if(!nextIsOdd) {
System.out.println(i);
i=i+2;
nextIsOdd = true;
}
}
}
}
});
Thread odd = new Thread(new Runnable()
{
public void run() {
int i = 1;
while(i<=200) {
synchronized(this) {
if(nextIsOdd) {
System.out.println(i);
i=i+2;
nextIsOdd = false;
}
}
}
}
});
odd.start();
even.start();
}
}
在任何情况下,为了避免可能的冲突,更优雅的答案是使用locks并从一个线程锁定,从另一个线程解锁。