Coding Threads in Java

I spent some time playing around with threads in Java this morning.

This examples comes from the Java docs dead lock example.

http://docs.oracle.com/javase/tutorial/essential/concurrency/deadlock.html
I’ve took some liberties with the names in the program and commented out the execution of the second thread. If the code is executed, these strings should be sent to standard out:

Alyssa P. Hacker: Bit Diddler has bowed to me!
Bit Diddler: Alyssa P. Hacker has bowed back to me!

As you can see once a person bows, the other person should bow back. So what happens if both people bow at the same time, well these strings should be sent to standard out along with pissing off Java:

Alyssa P. Hacker: Bit Diddler has bowed to me!
Bit Diddler: Alyssa P. Hacker has bowed to me!

When a person bows, they need to have their friend passed as a parameter and then their friend’s method bowBack is called. In this case both Alyssa and Bit are stuck looking at the ground.

public class Deadlock {
    static class Friend {
        private final String name;

        public Friend(String name) {
            this.name = name;
        }

        public String getName() {
            return this.name;
        }

        public synchronized void bow(Friend bower) {
            System.out.format("%s: %s"
                + "  has bowed to me!%n",
                this.name, bower.getName());
            bower.bowBack(this);
        }

        public synchronized void bowBack(Friend bower) {
            System.out.format("%s: %s"
                + " has bowed back to me!%n",
                this.name, bower.getName());
        }
    }

    public static void main(String[] args) {
        final Friend alyssa = new Friend("Alyssa P. Hacker");

        final Friend bit = new Friend("Bit Diddler");

        new Thread(new Runnable() {
            public void run() { alyssa.bow(gaston); }
        }).start();

       // new Thread(new Runnable() {
       //     public void run() { bit.bow(alphonse); }
       //}).start();
    }
}

 

So how do you get around this dead lock? Well with locks and a loops. This another example from the Java docs and it’s called SafeLock.

http://docs.oracle.com/javase/tutorial/essential/concurrency/deadlock.html

To make this concurrent, we need a Lock datatype and an never ending for loop. When it runs you can see where collision did occur but the program can still function and run. Here is short sample of what was send to my standard out when I ran this program.

Alyssa P. Hacker: Bit Diddler has bowed back to me!
Bit Diddler: Alyssa P. Hacker has bowed to me!
Alyssa P. Hacker: Bit Diddler has bowed back to me!
Alyssa P. Hacker: Bit Diddler started to bow to me, but saw that I was already bowing.
Bit Diddler: Alyssa P. Hacker has bowed to me!
Alyssa P. Hacker: Bit Diddler has bowed back to me!

As you can see when this string, “Alyssa P. Hacker: Bit Diddler started to bow to me, but saw that I was already bowing.”, occurred a collision happen but unlike the dead lock the program was able to continue the processing data.

import java.util.Random;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class SafeLock {
	static class Friend{
		private final String name;
		private final Lock lock = new ReentrantLock();

		public Friend(String name){ this.name = name; }

		public String getName(){ return this.name; }

		public boolean impendingBow(Friend bower){
			Boolean myLock = false;
			Boolean yourLock = false;
			try{
				myLock = lock.tryLock();
				yourLock = bower.lock.tryLock();

			} finally{
				if( ! (myLock && yourLock)){
					if (myLock)
						lock.unlock();
					if(yourLock)
						bower.lock.unlock();
				}
			}
			return myLock && yourLock;
		}

		public void bow(Friend bower){
			if (impendingBow(bower)){
				try{
					System.out.format("%s: %s has" + " bowed to me!%n",
							this.name, bower.getName());
					bower.bowBack(this);
				} finally {
					lock.unlock();
					bower.lock.unlock();
				}

			} else {
				System.out.format("%s: %s started" + " to bow to me, but saw that I was already bowing.%n",
						this.name, bower.getName());
			}
		}

		public void bowBack(Friend bower){
			System.out.format("%s: %s has bowed back to me!%n", this.name, bower.getName());
		}
	}

	static class BowLoop implements Runnable {
		private Friend bower;
		private Friend bowee;

		public BowLoop(Friend bower, Friend bowee){
			this.bower = bower;
			this.bowee = bowee;
		}

		public void run() {
			Random random = new Random();

			for(;;){
				try{
					Thread.sleep(random.nextInt(10));
				} catch (InterruptedException ex) {}
				bowee.bow(bower);
			}
		}
	}

	public static void main(String[] args){
		final Friend alyssa = new Friend("Alyssa P. Hacker");
		final Friend bit = new Friend("Bit Diddler");

		new Thread(new BowLoop(alyssa, bit)).start();
		new Thread(new BowLoop(bit, alyssa)).start();
	}
}
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s