Does this need explicit synchronization? - java

I have two threads, and I want to make sure I am doing the synchronization correctly on the LinkedBlockingQueue.. Is this correct? Or is the explicit synchronization on (messageToCommsQueue) not necessary?
Declaration:
private LinkedBlockingQueue<BaseMessage> messagesToCommsQueue;
Method one:
private void startOperationModeStatusMessageExecutor() {
ScheduledExecutorService operationModeStatusExecutor = Executors.newSingleThreadScheduledExecutor();
operationModeStatusExecutor.scheduleAtFixedRate((new Runnable() {
#Override
public void run() {
ModeStatusMessage commsOperateMsg;
commsOperateMsg = MessageFactory.getModeStatusMessage(status.ordinal());
synchronized (messagesToCommsQueue) {
messagesToCommsQueue.add(commsOperateMsg);
}
}
}), 0, 10, TimeUnit.SECONDS);
}
Method Two:
Executor commsSenderExecutor = Executors.newSingleThreadExecutor();
commsSenderExecutor.execute(new Runnable() {
#Override
public void run() {
while (getStatus().equals(ModeStatus.INITIATE) || getStatus().equals(ModeStatus.OPERATE)) {
BaseMessage m = null;
try {
synchronized (messagesToCommsQueue) {
m = messagesToCommsQueue.take();
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
});

Yes, it's not necessary. JavaDoc says that:
BlockingQueue implementations are thread-safe.

Related

Can static variables ever be used to synchronize threads?

Below I have constructed an example which synchronizes three threads based on a static variable:
public class CallMethodsInOrder {
public static void main(String[] args) {
// Three instances of Thread, first calls first, second second and third third.
// Ensure that they are all called in order.
Thread first = new Thread(new FooRunner(new Foo(),MethodToCall.FIRST));
Thread second = new Thread(new FooRunner(new Foo(),MethodToCall.SECOND));
Thread third = new Thread(new FooRunner(new Foo(),MethodToCall.THIRD));
third.start();
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
second.start();
first.start();
}
}
class Foo {
static boolean hasFirstRun = false;
static boolean hasSecondRun = false;
static boolean hasThirdRun = false;
public Foo() {
}
public void first() {
System.out.println("First");
hasFirstRun = true;
}
public void second() {
System.out.println("Second");
hasSecondRun = true;
}
public void third() {
System.out.println("Third");
hasThirdRun = true;
}
}
class FooRunner implements Runnable{
private Foo foo;
private MethodToCall method;
public FooRunner(Foo foo, MethodToCall method) {
this.foo = foo;
this.method = method;
}
#Override
public void run() {
if(method == MethodToCall.FIRST) {
foo.first();
}
else if (method == MethodToCall.SECOND){
while(!Foo.hasFirstRun) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
foo.second();
}
else if (method == MethodToCall.THIRD) {
while(!Foo.hasSecondRun) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
foo.third();
}
}
}
enum MethodToCall{
FIRST, SECOND, THIRD;
}
Is this a valid approach? I have read that static variables are not thread safe, however, cannot see a situation in which the above code would not execute the three methods in the desired order (first, second, third).
Many answers I have found have been related to accessing data structures with multiple threads vs ordering of methods as displayed here.
Since each static variable is only being modified by a single thread is it a problem?
As suggested in the comments, using synchronized is likely the way forward here. I feel the above code still works with static variables however is definitely not the best practise.
A related solution including Semaphores is included below:
public class CallMethodsInOrder2 {
public static void main(String[] args) {
// Three instances of Thread, first calls first, second second and third third.
// Ensure that they are all called in order.
// This approach uses Semaphore vs static variables.
Foo2 foo2 = new Foo2();
Thread first = new Thread(new FooRunner2(foo2,MethodToCall.FIRST));
Thread second = new Thread(new FooRunner2(foo2,MethodToCall.SECOND));
Thread third = new Thread(new FooRunner2(foo2,MethodToCall.THIRD));
third.start();
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
second.start();
first.start();
}
}
class Foo2 {
private Semaphore one, two;
public Foo2() {
one = new Semaphore(1);
two = new Semaphore(1);
try {
one.acquire();
two.acquire();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void first() {
System.out.println("First");
one.release();
}
public void second() {
try {
one.acquire();
System.out.println("Second");
one.release();
two.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void third() {
try {
two.acquire();
two.release();
System.out.println("Third");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
I think the static variable method 'works' in this case (for some value of 'works'), but is definitely less efficient.
You're sleeping an arbitrary amount of time in each thread ('100'), and then waking up to poll this variable. In the case of a semaphore, the OS takes care of the sleep/wake events to the threads.

Java synchronized block not working as expected

I am trying to implement a thread block using a map so that no more than one operation can be handled on a single customer at a time. This is talking to a web service and requires multiple steps to accomplish the full workflow. I need to be able to lock on a single customer at a time but allow other threads to execute without blocking the flow.
Here is my test cases to see how to get it working. What I am seeing is that the second thread cannot do get into the synchronized block of doSynchronizedSomething until the first thread has cleared. I thought this should work, but it is not working as expected.
Here are the results and you will notice that the millis are three seconds apart. I also checked to make sure that the CustomerLocks are not the same object in my test case. Is this possible?
Starting operation 123456 at time 1381173121688
Done with operation for 123456 at time 1381173124689
Starting operation 234567 at time 1381173124689
Done with operation for 234567 at time 1381173127690
Code
package simplethreadlock;
public class CustomerLock {
private String customerId;
public CustomerLock(String customerId) {
}
public String getCustomerId() {
return customerId;
}
public void setCustomerId(String customerId) {
this.customerId = customerId;
}
}
package simplethreadlock;
import java.util.concurrent.ConcurrentHashMap;
public class CustomerLockingMap {
private static ConcurrentHashMap<String, CustomerLock> locks = new ConcurrentHashMap<String, CustomerLock>();
public static CustomerLock aquireLock(String customerId) {
CustomerLock lock = locks.get(customerId);
if (lock == null) {
lock = new CustomerLock(customerId);
locks.put(customerId, lock);
}
return lock;
}
}
package simplethreadlock;
import org.junit.Assert;
import org.junit.Test;
public class CutomerLockingTest {
#Test
public void testLock() throws InterruptedException {
final String customerId1 = "123456";
final String customerId2 = "234567";
final CustomerLock customer1Lock1 = CustomerLockingMap
.aquireLock(customerId1);
final CustomerLock customer1Lock2 = CustomerLockingMap
.aquireLock(customerId1);
final CustomerLock customer2Lock1 = CustomerLockingMap
.aquireLock(customerId2);
final CustomerLock customer2Lock2 = CustomerLockingMap
.aquireLock(customerId2);
CountDownLatch latch = new CountDownLatch(1);
Assert.assertNotEquals(customer1Lock1, customer2Lock1);
new Thread(new Runnable() {
public void run() {
try {
doSynchronziedSomething(customer1Lock1, customerId1);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
new Thread(new Runnable() {
public void run() {
try {
doSynchronziedSomething(customer2Lock1, customerId2);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
new Thread(new Runnable() {
public void run() {
try {
doSynchronziedSomething(customer1Lock2, customerId1);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
new Thread(new Runnable() {
public void run() {
try {
doSynchronziedSomething(customer2Lock2, customerId2);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
latch.await(8, TimeUnit.SECONDS);
}
private void doSynchronziedSomething(final CustomerLock lock, final String customerId) throws InterruptedException {
synchronized (lock) {
System.out.println("Starting operation " + customerId + " at time "
+ System.currentTimeMillis());
Thread.sleep(3000);
System.out.println("Done with operation for " + customerId
+ " at time " + System.currentTimeMillis());
}
}
}
Edit
Silly me it is Thread.start() but if you are looking at the example for help on this I did add the CountDownLatch so that the unit test will not exit before the threads have had time to finish.
someThread.run()
is not a way to start a thread. It only runs that thread's internal runnable within the current thread, before any subsequent lines. Use .start() to actually start the thread as a thread, and let the two threads(and main thread) run simultaneously.
Thread#run() is a normal synchronous method call. What you want is Thread#start() which executes a native call to start the OS thread.

Testing PriorityBlockingQueue in ThreadPoolExecutor

I realized my ThreadPoolExecutor with PriorityBlockingQueue like in this example:
https://stackoverflow.com/a/12722648/2206775
and wrote a test:
PriorityExecutor executorService = (PriorityExecutor) PriorityExecutor.newFixedThreadPool(16);
executorService.submit(new Runnable() {
#Override
public void run() {
try {
Thread.sleep(1000);
Thread.sleep(1000);
System.out.println("1");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, 1);
executorService.submit(new Runnable() {
#Override
public void run() {
try {
Thread.sleep(1000);
Thread.sleep(1000);
System.out.println("3");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, 3);
executorService.submit(new Runnable() {
#Override
public void run() {
try {
Thread.sleep(1000);
Thread.sleep(1000);
System.out.println("2");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, 2);
executorService.submit(new Runnable() {
#Override
public void run() {
try {
Thread.sleep(1000);
Thread.sleep(1000);
System.out.println("5");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, 5);
executorService.submit(new Runnable() {
#Override
public void run() {
try {
Thread.sleep(1000);
Thread.sleep(1000);
System.out.println("4");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, 4);
executorService.shutdown();
try {
executorService.awaitTermination(30, TimeUnit.MINUTES);
} catch (InterruptedException e) {
e.printStackTrace();
}
But in the end, I don't get 1 2 3 4 5, I get a random order of those numbers. Is there a problem with the test, or something else? And if first, how can it be tested correctly?
The priority is only taken into account if the pool is fully busy and you submit several new tasks. If you define your pool with only one thread, you should get the expected output. In your example, all tasks get executed concurrently and which one finishes first is somewhat random.
By the way the linked implementation has a problem and throws an exception if your queue is full and you submit new tasks.
See below a working example of what you are trying to achieve (I have overriden newTaskFor in a simplistic way, just to make it work - you might want to improve that part).
It prints: 1 2 3 4 5.
public class Test {
public static void main(String[] args) {
PriorityExecutor executorService = (PriorityExecutor) PriorityExecutor.newFixedThreadPool(1);
executorService.submit(getRunnable("1"), 1);
executorService.submit(getRunnable("3"), 3);
executorService.submit(getRunnable("2"), 2);
executorService.submit(getRunnable("5"), 5);
executorService.submit(getRunnable("4"), 4);
executorService.shutdown();
try {
executorService.awaitTermination(30, TimeUnit.MINUTES);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static Runnable getRunnable(final String id) {
return new Runnable() {
#Override
public void run() {
try {
Thread.sleep(1000);
System.out.println(id);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
}
static class PriorityExecutor extends ThreadPoolExecutor {
public PriorityExecutor(int corePoolSize, int maximumPoolSize,
long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) {
super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
}
//Utitlity method to create thread pool easily
public static ExecutorService newFixedThreadPool(int nThreads) {
return new PriorityExecutor(nThreads, nThreads, 0L,
TimeUnit.MILLISECONDS, new PriorityBlockingQueue<Runnable>());
}
//Submit with New comparable task
public Future<?> submit(Runnable task, int priority) {
return super.submit(new ComparableFutureTask(task, null, priority));
}
//execute with New comparable task
public void execute(Runnable command, int priority) {
super.execute(new ComparableFutureTask(command, null, priority));
}
#Override
protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable) {
return (RunnableFuture<T>) callable;
}
#Override
protected <T> RunnableFuture<T> newTaskFor(Runnable runnable, T value) {
return (RunnableFuture<T>) runnable;
}
}
static class ComparableFutureTask<T> extends FutureTask<T> implements Comparable<ComparableFutureTask<T>> {
volatile int priority = 0;
public ComparableFutureTask(Runnable runnable, T result, int priority) {
super(runnable, result);
this.priority = priority;
}
public ComparableFutureTask(Callable<T> callable, int priority) {
super(callable);
this.priority = priority;
}
#Override
public int compareTo(ComparableFutureTask<T> o) {
return Integer.valueOf(priority).compareTo(o.priority);
}
}
}
You have 16 threads and only 5 tasks, meaning all of them are being executed concurrently and the priority is actually irrelevant.
The priority only matters when there are tasks waiting to be executed.
To show this, if you set your example to only use 1 thread, you will get your expected output.

Synchronize Is Blocking When I Try To CountDown

I followed the advice I found in this post using CountDownLatch and i'm running into a problem. I wrote up this test and ran it and my thread I created blocks when i try to synchronize on lock.
private CountDownLatch lock = new CountDownLatch(1);
#Test
public void testBlock() {
Runnable r = new Runnable() {
#Override
public void run() {
try
{
synchronized(this) {
this.wait(50);
}
}
catch (InterruptedException e)
{
e.printStackTrace();
throw (new RuntimeException(e));
}
releaseLock();
}
};
Thread t = new Thread(r);
t.setDaemon(true);
t.start();
waitOnCallback();
}
private void releaseLock() {
synchronized(lock) { // Thread t blocks here
lock.countDown();
}
}
private void waitOnCallback() {
synchronized(lock) {
try
{
lock.await();
}
catch (InterruptedException e)
{
throw new RuntimeException(e);
}
}
}
Why isn't this working?
A CountDownLatch is not an object on which you need to synchronize (i.e. remove the synchronized(lock) blocks). all thread-safety is handled internally to the object itself.

Wait until child threads completed : Java

Problem description : -
Step 1: Take input FILE_NAME from user at main thread.
Step 2: Perform 10 operations on that file (i.e count chars, count lines etc.. ), and all those 10 operations must be in septate threads. It means there must be 10 child threads.
Step 3: Main thread waits until all those child threads completed.
Step 4: Print result.
What I did :-
I did a sample code with 3 threads. I don't want file operation code from your side.
public class ThreadTest {
// This is object to synchronize on.
private static final Object waitObject = ThreadTest.class;
// Your boolean.
private static boolean boolValue = false;
public final Result result = new Result();
public static void main(String[] args) {
final ThreadTest mytest = new ThreadTest();
System.out.println("main started");
new Thread(new Runnable() {
public void run() {
System.out.println("Inside thread");
//Int initialiser
new Thread(new Runnable() {
public void run() {
System.out.println("Setting integer value");
mytest.result.setIntValue(346635);
System.out.println("Integer value seted");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
//String initialiser
new Thread(new Runnable() {
public void run() {
System.out.println("Setting string value");
mytest.result.setStringValue("Hello hi");
System.out.println("String value seted");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
//Boolean initialiser
new Thread(new Runnable() {
public void run() {
System.out.println("Setting boolean value");
mytest.result.setBoolValue(true);
System.out.println("Boolean value seted");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
System.out.println("Thread is finished");
//Notify to main thread
synchronized (ThreadTest.waitObject) {
ThreadTest.boolValue = true;
ThreadTest.waitObject.notifyAll();
}
}
}).start();
try {
synchronized (ThreadTest.waitObject) {
while (!ThreadTest.boolValue) {
ThreadTest.waitObject.wait();
}
}
} catch (InterruptedException ie) {
ie.printStackTrace();
}
System.out.println("main finished");
System.out.println("Result is : " + mytest.result.toString());
}
}
Problem :-
My above code is not giving correct answer. How can I do that?
Alternate solutions:
CountDownLatch class does the same. But I don't want to use that class.
I looked this similar solution and I want to use methods of Thread only.
You can do:
Thread t = new Thread() {
public void run() {
System.out.println("text");
// other complex code
}
};
t.start();
t.join();
This way you will wait until the thread finishes and just then continue. You can join multiple threads:
for (Thread thread : threads) {
thread.join();
}
I would recommend looking at the Executors framework first, and then look into the CompletionService.
Then you can write something like this:
ExecutorService executor = Executors.newFixedThreadPool(maxThreadsToUse);
CompletionService completion = new ExecutorCompletionService(executor);
for (each sub task) {
completion.submit(new SomeTaskYouCreate())
}
// wait for all tasks to complete.
for (int i = 0; i < numberOfSubTasks; ++i) {
completion.take(); // will block until the next sub task has completed.
}
executor.shutdown();
In Java 8 a far better approach is to use parallelStream()
Note: it is far easier to see exactly what these background tasks are doing.
public static void main(String[] args) {
Stream.<Runnable>of(
() -> mytest.result.setIntValue(346635),
() -> mytest.result.setStringValue("Hello hi"),
() -> mytest.result.setBoolValue(true) )
.parallel()
.forEach(Runnable::run);
System.out.println("main finished");
System.out.println("Result is : " + mytest.result.toString());
}
I took out the debug information and the sleep as these don't alter the outcome.
You may want to choose CountDownLatch from java.util.concurrent. From JavaDocs:
A synchronization aid that allows one or more threads to wait until a
set of operations being performed in other threads completes.
Sample code:
import java.util.concurrent.CountDownLatch;
public class Test {
private final ChildThread[] children;
private final CountDownLatch latch;
public Test() {
this.children = new ChildThread[4];
this.latch = new CountDownLatch(children.length);
children[0] = new ChildThread(latch, "Task 1");
children[1] = new ChildThread(latch, "Task 2");
children[2] = new ChildThread(latch, "Task 3");
children[3] = new ChildThread(latch, "Task 4");
}
public void run() {
startChildThreads();
waitForChildThreadsToComplete();
}
private void startChildThreads() {
Thread[] threads = new Thread[children.length];
for (int i = 0; i < threads.length; i++) {
ChildThread child = children[i];
threads[i] = new Thread(child);
threads[i].start();
}
}
private void waitForChildThreadsToComplete() {
try {
latch.await();
System.out.println("All child threads have completed.");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private class ChildThread implements Runnable {
private final String name;
private final CountDownLatch latch;
protected ChildThread(CountDownLatch latch, String name) {
this.latch = latch;
this.name = name;
}
#Override
public void run() {
try {
// Implementation
System.out.println(name + " has completed.");
} finally {
latch.countDown();
}
}
}
public static void main(String[] args) {
Test test = new Test();
test.run();
}
}
Output:
Task 1 has completed.
Task 4 has completed.
Task 3 has completed.
Task 2 has completed.
All child threads have completed.
There are many ways to approach this. Consider CountDownLatch:
import java.util.concurrent.CountDownLatch;
public class WorkerTest {
final int NUM_JOBS = 3;
final CountDownLatch countDownLatch = new CountDownLatch(NUM_JOBS);
final Object mutex = new Object();
int workData = 0;
public static void main(String[] args) throws Exception {
WorkerTest workerTest = new WorkerTest();
workerTest.go();
workerTest.awaitAndReportData();
}
private void go() {
for (int i = 0; i < NUM_JOBS; i++) {
final int fI = i;
Thread t = new Thread() {
public void run() {
synchronized(mutex) {
workData++;
}
try {
Thread.sleep(fI * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
countDownLatch.countDown();
}
};
t.start();
}
}
private void awaitAndReportData() throws InterruptedException {
countDownLatch.await();
synchronized(mutex) {
System.out.println("All workers done. workData=" + workData);
}
}
}
Check if all child threads are dead, every n seconds. Simple, yet effective method:
boolean allDead=false;
while(! allDead){
allDead=true;
for (int t = 0; t < threadCount; t++)
if(threads[t].isAlive()) allDead=false;
Thread.sleep(2000);
}

Categories

Resources