简体   繁体   English

使用两个线程依次使用自定义锁打印号码,其中一个正在打印,而另一个正在打印奇数

[英]Using custom lock print number in sequence using two threads where one is printing even other is printing odd numbers

There are two threads,one is to print even numbers another prints odd numbers. 有两个线程,一个是打印偶数,另一个是打印奇数。 With the help of below custom lock i want to print number in sequence. 在下面的自定义锁的帮助下,我想按顺序打印数字。 The problem is after printing some numbers(displayed number are in correct sequence.) threads are getting deadlocked.I spent more then an hour still unable to find issue,for me everything seems fine. 问题是在打印了一些数字后(显示的数字按正确的顺序显示。)线程陷入僵局。我花了一个多小时仍找不到问题,对我来说一切似乎都很好。

public class Main{
       public static void main(String[] args){
           Lock lock=new Lock();
           SharedData sharedData=new SharedData(lock);

           Thread th1=new Thread(new EvenWriter(sharedData));
           Thread th2=new Thread(new OddWriter(sharedData));

           th1.start();
           th2.start();
       } 
    }
    class SharedData{
        Lock lock;
        boolean printOdd;
        SharedData(Lock lock){
           this.lock=lock;
           this.printOdd=true;
        }
    }
    class OddWriter implements Runnable{
        SharedData sharedData;
        int num;
        Lock lock;
        public OddWriter(SharedData sharedData){
           this.sharedData=sharedData;
           this.num=1;
           this.lock=sharedData.lock;
        }
        public void run(){
           while(true){
             if(sharedData.printOdd){
               lock.lock();
               System.out.println(num);
               num=num+2;
               sharedData.printOdd=false;
               lock.unlock();
            }
           }
        }
    }
    class EvenWriter implements Runnable{
        SharedData sharedData;
        int num;
        Lock lock;
        public EvenWriter(SharedData sharedData){
           this.sharedData=sharedData;
           this.num=2;
           this.lock=sharedData.lock;
        }
        public void run(){
           while(true){
             if(!sharedData.printOdd){
               lock.lock();
               System.out.println(num);
               num=num+2;
               sharedData.printOdd=true;
               lock.unlock();
            }
           }
        }
    }
    class Lock{

        private boolean locked=false;
        public synchronized void lock(){

            while(locked){
               try{
                 wait();
               }
               catch(Exception e){
                   e.printStackTrace();
               }
            }

            locked=true;
        }
        public synchronized void unlock(){
            locked=false;
            try{
              notifyAll();
            }
            catch(Exception e){
               e.printStackTrace();
            }
        }
    }

You need to make printOdd volatile , eg 您需要使printOdd volatile ,例如

class SharedData{
    Lock lock;
    volatile boolean printOdd;
    SharedData(Lock lock) {
       this.lock=lock;
       this.printOdd=true;
    }
}

This is because you use printOdd across multiple threads; 这是因为您在多个线程中使用了printOdd the purpose of volatile is to ensure that a piece of memory is accessible by all threads. volatile的目的是确保所有线程都可以访问一块内存。 What you were doing before was allowing access of printOdd to just the OddWriter thread, because it was the first thread to access it. 您之前所做的是只允许对OddWriter线程访问printOdd ,因为它是第一个访问它的线程。

the data that is shared between two thread is to be atomic. 两个线程之间共享的数据是原子的。 Here in your case the boolean printOdd is shared between the thread which is the cause for the deadlock. 在这种情况下,线程之间共享boolean printOdd ,这是导致死锁的原因。 Can you used 你可以用吗

AtomicBoolean printOdd;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM