当前位置: 首页 > 知识库问答 >
问题:

使用两个线程按顺序自定义锁定打印号码,其中一个线程打印偶数,另一个线程打印奇数

郗丰
2023-03-14

有两个线程,一个是打印偶数,另一个是打印奇数。在下面自定义锁的帮助下,我想按顺序打印数字。问题出在打印一些数字后(显示的数字顺序正确。)线程越来越死机。我花了一个多小时还是找不到问题,对我来说一切都很好。

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();
            }
        }
    }

共有1个答案

姚自强
2023-03-14

您需要使printoddvolatile,例如。

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

这是因为您跨多个线程使用printoddvolatile的目的是确保所有线程都可以访问一块内存。您以前所做的是只允许printodd访问oddwriter线程,因为它是第一个访问它的线程。

 类似资料:
  • 问题内容: 我正在尝试使用2个不同的线程交替打印奇数和偶数。我能够使用等待,通知和同步块来实现它,但是现在我想评估是否可以不使用等待,通知和同步来实现它。 以下是我拥有的代码,但无法正常工作: } 有任何想法吗? 根据Bruno的建议,我创建了另一个版本,该版本似乎效果更好: 问题答案: 代码未正确同步,这就是问题所在。 您的代码中允许以下执行顺序: 第一个线程看到,将其设置为并进入块。 第二个线

  • 问题内容: 使用线程进行奇数打印,创建一个线程类,两个线程实例。 一个将打印奇数,而另一个将打印偶数。 我做了以下编码。但这涉及到死锁状态。有人可以解释一下原因吗? 输出: 奇数1偶数2 然后陷入僵局!!!!!! 谢谢你的帮助。 问题答案: 您正在等待并通知其他对象( 监视器 )。 这个想法是,你在做和做的时候可以打电话等待一个人做。 将您的方法更改为类似 和方法类似。 然后为提供一个对象: 输出

  • 我试图创建一个实现,其中多个线程打印序列的备用值。这里thread1将打印1,4,7 thread2将打印2,5,8 thread3将打印3,6,9。我用的是原子整数和模函数。 下面的实现可以很好地工作,第一个线程打印1,4,7,第二个线程打印2,5,8,第三个线程打印3,6,9,但问题是没有保持顺序,即输出可能类似于1,3,2,4,5,7,8,6,9,而我希望保持顺序,因为正确的线程可以打印这些

  • 这个问题是在电子艺术采访中提出的。 有三条线。第一个线程打印1到10个数字。第二个线程打印从11到20的数字。第三条线从21到30。现在这三个线程都在运行。然而,数字是按不规则的顺序打印的,如1、11、2、21、12等。 如果我想让数字按排序顺序打印,比如1,2。。。我该怎么处理这些线呢?

  • 我正在回答以下面试问题: 一个进程有三个线程。第一个线程打印1 1 1...,第二个打印2 2 2...,第三个打印3 3 3...无休止。你如何安排这三个线程以打印1 2 3 1 2 3... 我想出了下面的代码,使用两个线程打印,但我无法找出如何从第三个线程在这里打印数字的条件。 如何有效地解决这类问题?

  • 采访中问 有三条线。第一条线打印100到199个数字。第二个线程打印200到299之间的数字。第三条线从300到399。执行的顺序是