Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8712917
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 13, 20262026-06-13T05:12:51+00:00 2026-06-13T05:12:51+00:00

I’m trying to remember my old CS days. Been trying to properly implement, with

  • 0

I’m trying to remember my old CS days.

Been trying to properly implement, with the lowest possible primitives, a pair of synchronized threads. Of course I should use better concurrency tools on production code (stuff from java.util.concurrency, probably). But hey, I’m doing this for the challenge. Here is my code (this is my first question, so if this is much too long, please forgive me):

public class Test {

    public volatile Object locker1 = new Object();
    public volatile Object locker2 = new Object();
    public volatile Object locker3 = new Object();

    public class MyRunnable2 implements Runnable {
        public void run() {

            System.out.println( "MyRunnable2 started" );



            synchronized( locker3 ) {
                    try {
                        System.out.println( "r2: waiting for locker3" );
                        locker3.wait();
                        System.out.println( "r2: got locker3" );
                    } catch ( java.lang.InterruptedException e ) {
                        System.out.println( "e: " + e );
                    }
            }



            for ( int c = 0; c < 50; ++c ) {

                synchronized( locker2 ) {

                    try {
                        System.out.println( "r2: waiting for locker2" );
                        locker2.wait();
                        System.out.println( "r2: got locker2" );
                    } catch ( java.lang.InterruptedException e ) {
                        System.out.println( "e: " + e );
                    }
                }

                System.out.println( "r2: " + ( c ) );
                try {
                    Thread.sleep(1);
                } catch ( Exception e ) {
                }

                synchronized( locker1 ) {
                    System.out.println( "r2: signaling locker1" );
                    locker1.notify();
                    System.out.println( "r2: locker1 signaled" );
                }
            }
        }
    }

    public class MyRunnable1 implements Runnable {
        public void run() {
            System.out.println( "MyRunnable1 started" );

            synchronized( locker3 ) {
                    try {
                        System.out.println( "r1: waiting for locker3" );
                        locker3.wait();
                        System.out.println( "r1: got locker3" );
                    } catch ( java.lang.InterruptedException e ) {
                        System.out.println( "e: " + e );
                    }
            }

            for ( int c = 0; c < 50; ++c ) {


                synchronized( locker1 ) {

                    try {
                        System.out.println( "r1: waiting for locker1" );
                        locker1.wait();
                        System.out.println( "r1: got locker1" );
                    } catch ( java.lang.InterruptedException e ) {
                        System.out.println( "e: " + e );
                    }
                }

                System.out.println( "r1: " + ( c ) );
                try {
                    Thread.sleep(1);
                } catch ( Exception e ) {
                }

                synchronized( locker2 ) {
                    System.out.println( "r1: signaling locker2" );
                    locker2.notify();
                    System.out.println( "r1: locker2 signaled" );
                }

            }
        }
    }

    public static void main(String[] args) {
        Test t = new Test();
        t.test();
    }

    public void test() {
        MyRunnable1 r1 = new MyRunnable1();
        MyRunnable2 r2 = new MyRunnable2();
        Thread t1 = new Thread( r1 );
        Thread t2 = new Thread( r2 );
        t1.start();
        t2.start();

        try {
            Thread.sleep(1000);
        } catch ( Exception e ) {

        }
        synchronized( locker3 ) {
            System.out.println( "main: signaling locker3" );
            locker3.notifyAll();
            System.out.println( "main: locker3 signaled" );
        }

        try {
            Thread.sleep(1000);
        } catch ( Exception e ) {

        }

        synchronized( locker1 ) {
            System.out.println( "main: signaling locker1" );
            locker1.notify();
            System.out.println( "main: locker1 signaled" );
        }


        try {
            t1.join();
            t2.join();


        } catch ( java.lang.InterruptedException e ) {
            System.out.println( "e: " + e );
        }
    }
}

My question is: How can I avoid the race condition at Test.test()? Most of the time, this works – but I’m not satisfied with the sleep call.
Also, please, I ask you people to evaluate my style. I’m always open to self-improvement.

EDIT: Just to make it clearer. I want MyRunnable1 to always run first. Print a number and then wait for MyRunnable2 to print the same number. Then it would print a second number and then wait for MyRunnable2 again. And so on.

I guess I can’t comfortably use java.util.concurrency until I know what happens under the hood.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-13T05:12:53+00:00Added an answer on June 13, 2026 at 5:12 am

    @Chris Thompson is right – you can alternate on a single signal object. But you will never guarantee which thread goes first and you have to take some care to make sure that you don’t have your last thread waiting for your second-to-last-thread to notify after your second-to-last thread has already finished and exited.

    I modified your code to work – but with no guarantee on who goes first, then I also added an alternate “MyRunnableOrdered” that controls the order the two threads execute. In either case if the threads do not have the same number of loops to complete, or if either one exits because of an error, then you will risk starvation. Paying attention to and using the interrupted exception will help in the latter case.

    public class Test {
    
    public Object locker = new Object();
    public boolean oneDone = false;
    
    public class MyRunnable2 implements Runnable {
        public void run() {
    
            System.out.println( "MyRunnable2 started" );
    
            for ( int c = 0; c < 50; ++c ) {
                synchronized( locker ) {
                    System.out.println( "r2: " + ( c ) );
                    locker.notify();
                    if(c == 49) {
                        oneDone = true;
                    }
    
                    try {
                        if(!oneDone) {
                            locker.wait();
                        }
                    } catch ( java.lang.InterruptedException e ) {
                        System.out.println( "e: " + e );
                    }                    
                }
            }
        }
    }
    
    public class MyRunnable1 implements Runnable {
        public void run() {
            System.out.println( "MyRunnable1 started" );
    
            for ( int c = 0; c < 50; ++c ) {
                synchronized( locker ) {
                    System.out.println( "r1: " + ( c ) );
                    locker.notify();
                    if(c == 49) {
                        oneDone = true;
                    }
    
                    try {
                        if(!oneDone) {
                            locker.wait();
                        }
                    } catch ( java.lang.InterruptedException e ) {
                        System.out.println( "e: " + e );
                    }
                }
            }
        }
    }
    
    
    public Object sequenceLock = new Object();
    public boolean sequence = true;
    
    public class MyRunnableOrdered implements Runnable {
    
        private final boolean _match;
    
        public MyRunnableOrdered(boolean match) 
        {
            _match = match;
        }
    
        public void run() {
            System.out.println( "MyRunnable1 started" );
    
            for ( int c = 0; c < 50; ++c ) {
                synchronized( sequenceLock ) {
                    while(_match != sequence) {
                        try {
                            sequenceLock.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
    
                    System.out.println( "r" + _match + ":" + ( c ) );
                    sequence = !sequence;
                    sequenceLock.notify();
                }
            }
        }
    }    
    
    
    public static void main(String[] args) {
        Test t = new Test();
        t.test();
    }
    
    public void test() {
        MyRunnable1 r1 = new MyRunnable1();
        MyRunnable2 r2 = new MyRunnable2();
        Thread t1 = new Thread( r1 );
        Thread t2 = new Thread( r2 );
    
    
        synchronized( locker ) {
            t1.start();
            t2.start();
        }
    
    
        try {
            t1.join();
            t2.join();
        } catch ( java.lang.InterruptedException e ) {
            System.out.println( "e: " + e );
        }
    
        System.out.println("Done part 1");
    
        MyRunnableOrdered o1 = new MyRunnableOrdered(true);
        MyRunnableOrdered o2 = new MyRunnableOrdered(false);
        synchronized(sequenceLock) {
            sequence = true;
        }
        Thread to1 = new Thread( o1 );
        Thread to2 = new Thread( o2 );
        to1.start();
        to2.start();
    
        try {
            to1.join();
            to2.join();
        } catch ( java.lang.InterruptedException e ) {
            System.out.println( "e: " + e );
        }       
        System.out.println("Done part 2");
    }
    }
    

    Note that the MyRunnableOrdered idea will not extend beyond two threads, because we do not control who wakes up when notify is called. What you would want in that case is an ordered list of threads to work through. At that point concurrency may not be the best solution!

    There is also probably a better implementation of MyRunnableOrdered using AtomicBoolean and no locking if you decide to use the concurrency library.

    Also note that we do not need to use “volatile” because all the variable access is protected by synchronized blocks.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I'm trying to convert HTML to plain text. I get many &\#8217; &\#8220; etc.
I am trying to understand how to use SyndicationItem to display feed which is
Basically, what I'm trying to create is a page of div tags, each has
I have a string like this: La Torre Eiffel paragonata all&#8217;Everest What PHP function
link Im having trouble converting the html entites into html characters, (&# 8217;) i
I am trying to render a haml file in a javascript response like so:
I'm parsing an RSS feed that has an &#8217; in it. SimpleXML turns this
I'm trying to select an H1 element which is the second-child in its group
I have a text area in my form which accepts all possible characters from
I'm trying to decode HTML entries from here NYTimes.com and I cannot figure out

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.