Proxy design pattern for implementing thread safe wrappers
Q. What are the different ways you can make an object thread-safe?
A.
- Synchronize critical sections: An object's critical sections are those methods or blocks of code within methods that must be executed by only one thread at a time. By using Java's synchronized keyword, you can guarantee that only one thread at a time will ever execute the object's critical sections.
- Make the object immutable. Immutable objects are, by their very nature, thread-safe simply because threads have to be able to write to an object's instance variables to experience a read/write or write/write conflict.
- Use a thread-safe wrapper: by applying the proxy design pattern. let's have a look at an example.
Step 1: Here are the sample third party interface and implementation classes.
Here is the Interface
package com.arul; public interface ThirdPartyInterface { abstract void someMethod(); }
Here is the implementation
package com.arul; public class ThirdPartyImpl implements ThirdPartyInterface { private int someVar = 0; @Override public void someMethod() { //some not thread safe functionality System.out.println("Printing .........." + ++someVar); } }
Step 2: Here is the testing of original third-party library to prove that it is not thread-safe.
package com.arul; public class TestThreadSafeThirdParty implements Runnable { private ThirdPartyInterface tstp = null; public TestThreadSafeThirdParty(ThirdPartyInterface tstp) { this.tstp = tstp; } public static void main(String[] args) { ThirdPartyImpl localTp = new ThirdPartyImpl(); TestThreadSafeThirdParty test = new TestThreadSafeThirdParty(localTp); //create 2 threads Thread thread1 = new Thread(test); Thread thread2 = new Thread(test); thread1.start(); thread2.start(); } @Override public void run() { for (int i = 0; i < 5; i++) { tstp.someMethod(); } } }
The output of the above run is not thread-safe as shown below
Printing ..........1 Printing ..........3 Printing ..........2 Printing ..........4 Printing ..........5 Printing ..........6 Printing ..........7 Printing ..........9 Printing ..........8 Printing ..........10
Step 3: Here is the thread safe implementation that acts as a proxy to the subject, and its responsibility is to add thread-safety.
package com.arul; /** * proxy class that applies thread safety to */ public class ThreadSafeThirdPartyImpl implements ThirdPartyInterface { private final Object lock = new Object(); private final ThirdPartyInterface subject; public ThreadSafeThirdPartyImpl(ThirdPartyInterface subject) { this.subject = subject; } @Override public void someMethod() { //lock to provide thread safety via this proxy class synchronized (lock) { try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); } subject.someMethod(); //access the unsafe method } } }Step 4: Here is the testing of proxied third-party library to prove that it is now thread-safe.
package com.arul; public class TestThreadSafeThirdParty implements Runnable { private ThirdPartyInterface tstp = null; public TestThreadSafeThirdParty(ThirdPartyInterface tstp) { this.tstp = tstp; } public static void main(String[] args) { ThirdPartyImpl localTp = new ThirdPartyImpl(); ThreadSafeThirdPartyImpl localTsTp = new ThreadSafeThirdPartyImpl(localTp); TestThreadSafeThirdParty test = new TestThreadSafeThirdParty(localTsTp); //create 2 threads Thread thread1 = new Thread(test); Thread thread2 = new Thread(test); thread1.start(); thread2.start(); } @Override public void run() { for (int i = 0; i < 5; i++) { tstp.someMethod(); } } }The output of the above run is now thread-safe as shown below. Thanks to the proxy class that applies the lock.
Printing ..........1 Printing ..........2 Printing ..........3 Printing ..........4 Printing ..........5 Printing ..........6 Printing ..........7 Printing ..........8 Printing ..........9 Printing ..........10
Other design patterns - real life examples
- Sharing and reusing objects with the flyweight design pattern in Java
- When to use a builder design pattern? real life tips
- Deadlock Retry with JDK Dynamic Proxy
- Java I/O -- the Decorator and proxy design pattern interview questions and answers
- Java design pattern interview questions and answers: strategy and factory pattern
- Sharing and reusing objects with the flyweight design pattern in Java
- Observer design pattern for publish/Subscribe model
Labels: design pattern
0 Comments:
Post a Comment
Subscribe to Post Comments [Atom]
<< Home