在java中同步原始inetger值

时间:2015-05-15 14:53:02

标签: java multithreading synchronization primitive

我有两个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();


}

}

2 个答案:

答案 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并从一个线程锁定,从另一个线程解锁。