为什么输出不同步?

时间:2014-04-30 07:36:31

标签: java multithreading thread-synchronization

我正在尝试学习多线程

public class WithSynchronizeMethodObject extends Thread
{
    SharedObject obj;
    WithSynchronizeMethodObject()
    {

    }

    WithSynchronizeMethodObject(SharedObject o)
    {
        obj=o;
    }

    @Override
    public void run()
    {
        for(int i=0;i<5;i++)
        {
            try
            {
                //calling object of method to add and print value, real life scenario performing any other operation
                obj.addAndPrint();                  int sleepTime=getRandom();
                System.out.println(" "+getName()+" sleep time is "+sleepTime);

                    //randomly making thread sleep,
                    Thread.sleep(sleepTime);


            }
            catch(InterruptedException ie)
            {

            }
        }
    }

    int getRandom()
    {
        int range = Math.abs(900) + 100;
        double random=Math.random() * range;
        return (int)((random<100)?(100+random):random) ;
    }
    public static void main(String args[])
    {
        SharedObject obj=new SharedObject();

        //passing same object in both threads
        WithSynchronizeMethodObject withOutObj1=new WithSynchronizeMethodObject(obj);
        WithSynchronizeMethodObject withOutObj2=new WithSynchronizeMethodObject(obj);

        //starting both thread almost together, 
        withOutObj1.start();
        withOutObj2.start();
    }
}
//custom shared object
class SharedObject
{
    int i;
    SharedObject()
    {
        i=0;
    }

    synchronized void addAndPrint()
    {
        ++i;
        System.out.print("i="+i);
    }
}

输出:

i=1 Thread-0 sleep time is 236
i=2 Thread-1 sleep time is 455
i=3 Thread-0 sleep time is 401
i=4 Thread-1 sleep time is 133
i=5 Thread-1 sleep time is 983
i=6 Thread-0 sleep time is 160
i=7 Thread-0 sleep time is 456
i=8 Thread-0 sleep time is 182
i=9 Thread-1 sleep time is 146
i=10 Thread-1 sleep time is 661

修改

制作对象同步

synchronized(obj)
            {
                try
                {
                    obj.addAndPrint();
                    int sleepTime=getRandom();
                    System.out.println(" "+getName()+" sleep time is "+sleepTime);

                    //randomly making thread sleep,
                    Thread.sleep(sleepTime);

                }
                catch(InterruptedException ie)
                {

                }
            }

显示两个不一致的输出 输出:

1

i=1 Thread-0 sleep time is 299
i=2 Thread-0 sleep time is 154
i=3 Thread-0 sleep time is 736
i=4 Thread-0 sleep time is 635
i=5 Thread-0 sleep time is 180
i=6 Thread-1 sleep time is 489
i=7 Thread-1 sleep time is 201
i=8 Thread-1 sleep time is 115
i=9 Thread-1 sleep time is 397
i=10 Thread-1 sleep time is 877

2

i=1 Thread-0 sleep time is 618
i=2 Thread-0 sleep time is 125
i=3 Thread-0 sleep time is 170
i=4 Thread-0 sleep time is 705
i=5 Thread-1 sleep time is 431
i=6 Thread-1 sleep time is 738
i=7 Thread-0 sleep time is 821
i=8 Thread-1 sleep time is 296
i=9 Thread-1 sleep time is 536
i=10 Thread-1 sleep time is 143

Q.1为什么输出不同步,如何使其同步运行?

Q.2还有什么其他方法,我知道几个Locks和wait / notify?

Q.3哪一个以及它们如何帮助同步?

1 个答案:

答案 0 :(得分:1)

  

为什么输出不同步,如何使其同步运行?

输出已同步。每一行都是完整和正确的。如果没有同步,你会在另一行内看到一些行。

我认为你的意思;

  

我怎样才能锁定整个循环?

在循环之外添加

synchronized(sharedObject) {

}

最后。

  

还有什么其他方法,我知道很少有锁和等待/通知?

我强烈建议你阅读Java Concurrency in Practice一书。这是一本很好的书,可能是最好的Java书。

  

哪一个以及它们如何帮助同步?

他们有许多相互关联的功能

  • 使用比较和设置的组合获得对资源的独占访问,可能是某些状态,例如等待线程的队列,如果存在长时间延迟则调用OS。
  • 读/写内存屏障,以便您获得在类似代码块中读/写的任何内容的一致视图。
  • 解锁通常会检查这是否正确调用。
  • 还可以监视某些锁定,以便您可以看到死锁和等待锁定。