Java synchronization(object locking) not working as expected - java

Please consider the below code.
import static java.lang.System.out;
public class Task
{
public Integer k = new Integer(10) ;
public Task()
{
out.println(k + " constructor of Task : " + Thread.currentThread().getName());
}
}
import static java.lang.System.out;
public class Executor2 implements Runnable
{
private Task task;
public Executor2(Task t)
{
out.println("constructor of Executor2 : " + Thread.currentThread().getName());
task = t;
}
#Override
public void run()
{
synchronized(task.k)
{
task.k = 88;
out.println("changed value of task.k to : " + task.k + " " + Thread.currentThread().getName());
try
{
out.println("sleeping");
Thread.sleep(5000);
}
catch (InterruptedException ex)
{
ex.printStackTrace(out);
}
out.println("done");
}
}
}
import static java.lang.System.out;
public class Executor3 implements Runnable
{
private Task task;
public Executor3(Task t)
{
out.println("constructor of Executor3 : " + Thread.currentThread().getName());
task = t;
}
#Override
public void run()
{
synchronized(task.k)
{
task.k = 888;
out.println("changed value of task.k to : " + task.k + " " + Thread.currentThread().getName());
}
}
}
------------------------------------------------------------
public class Main
{
public static void main(String[] args)
{
Task task = new Task();
Executor2 executor2 = new Executor2(task);
Thread thread2 = new Thread(executor2);
thread2.start();
Executor3 executor3 = new Executor3(task);
Thread thread3 = new Thread(executor3);
thread3.start();
}
}
Below is the output of the program.
10 constructor of Task : main
constructor of Executor2 : main
constructor of Executor3 : main
changed value of task.k to : 88 Thread-0
sleeping
changed value of task.k to : 888 Thread-1
done
The surprising thing here is output line : changed value of task.k to : 888 Thread-1 which is not expected to be printed before output line : done.
How come the lock on Integer object is released before sleep duration has passed?
Thanks.

synchronized(task.k)
{
task.k = 888;
Changing the object you're synchronizing on kind of defeats the point of the synchronization. You then try to print the new object while you're still synchronized on the old one. Don't replace objects threads are synchronizing on!

Extending what David Schwartz said: In almost all cases, if you're going to write this:
synchronized (foo) {
...
}
Then the variable that refers to the lock object should be a final field:
class MyClass {
final Object foo = new Object();
...
void someMethod(...) {
synchronized (foo) {
...
}
}
...
}
That will prevent you from making the same mistake in the future.

Agree with above. Also while using private lock, one pitfall is not to lock on string literals - String literals are shared resource.
private final String lock = “xx”;
private final String lock = new String(“xxx”);
The second locking is fine.

Related

How to find the result of first thread that finishes successfully in java?

Suppose there are multiple threads trying to find a value, whichever thread finds it first should send the output to the main thread and all other threads should be terminated.
Example -
public class WorkerThread implements Runnable {
#Override
public void run() {
// some long task here, returns int value
}
}
public class Main {
public static void main(String[] args){
// initialize multiple worker threads here
// then get result from the thread that completes first
}
}
I looked into docs and found invokeAny ExecutorService but this will return the result of any thread that has been completed successfully and not necessarily the first one.
As #Andy Turner said, use a CompletionService:
public static class WorkerThread implements Callable<Integer> {
#Override
public Integer call() throws Exception {
int nextInt = new Random().nextInt(10000);
try {
System.out.println("I will cost " + nextInt + " ms to finish job.--" + Thread.currentThread().getName());
Thread.sleep(nextInt);
} catch (InterruptedException ite) {
System.out.println("I am interrupted.--" + Thread.currentThread().getName());
return -1;
}
System.out.println("I am finish.--" + Thread.currentThread().getName());
return nextInt;
}
}
public static void main(String[] args) throws InterruptedException, ExecutionException {
int nums = 3;
ExecutorService executorService = Executors.newFixedThreadPool(nums);
CompletionService<Integer> completionService = new ExecutorCompletionService<>(executorService);
while (nums-- > 0) {
completionService.submit(new WorkerThread());
}
Integer firstValue = completionService.take().get();
System.out.println("FirstValue is " + firstValue);
executorService.shutdownNow();
}
And you can see in output, only one thread will complete the job (Because only call completionService#take once
), other threads will be interrupted and exit
:
I will cost 8943 ms to finish job.--pool-1-thread-1
I will cost 9020 ms to finish job.--pool-1-thread-2
I will cost 5025 ms to finish job.--pool-1-thread-3
I am finish.--pool-1-thread-3
FirstValue is 5025
I am interrupted.--pool-1-thread-1
I am interrupted.--pool-1-thread-2
You can also use CountDownLatch and ExecutorService for achieving this.
Create CountDownLatch object with count = 1.
CountDownLatch latch = new CountDownLatch(1);
Use ExecutorService pool to execute the threads and pass the latch in all the threads.
workerThreadPool.execute(new WorkerThread(latch));
Wait for any thread to complete it's operation.
latch.await();
In the finally block of the thread run, shutdown the latch.
latch.countDown();
As soon as any thread countDown's the latch, the threadpool will stop all the other threads and shutdown.
workerThreadPool.shutdownNow();
The complete example would be below.
import static java.lang.Thread.sleep;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
class WorkerThread implements Runnable
{
CountDownLatch _latch;
public WorkerThread(CountDownLatch latch)
{
_latch = latch;
}
#Override
public void run()
{
try
{
// some long task here, returns int value
System.out.println("In thread1 " + this.toString());
sleep(5000);
}
catch (InterruptedException ex)
{
System.out.println("thread1 interupted");
}
finally
{
System.out.println("Finished1 " + this.toString());
_latch.countDown();
}
}
}
class WorkerThread2 implements Runnable
{
CountDownLatch _latch;
public WorkerThread2(CountDownLatch latch)
{
_latch = latch;
}
#Override
public void run()
{
try
{
// some long task here, returns int value
System.out.println("In thread2 " + this.toString());
sleep(10000);
}
catch (InterruptedException ex)
{
System.out.println("thread2 interupted");
}
finally
{
System.out.println("Finished2 " + this.toString());
_latch.countDown();
}
}
}
public class Main
{
public static void main(String[] args) throws InterruptedException
{
ExecutorService workerThreadPool = Executors.newFixedThreadPool(2);
CountDownLatch latch = new CountDownLatch(1);
workerThreadPool.execute(new WorkerThread(latch));
workerThreadPool.execute(new WorkerThread2(latch));
latch.await();
workerThreadPool.shutdownNow();
}
}
You -could- pass a reference to the Thread where the Thread can send its results. But you'd better follow advice in the other answers and use a better API for this :)
public static void main(//) {
ResultConsumer r = new ResultConsumer();
... create and start worker threads
}
public class WorkerThread implements Runnable {
public WorkerThread ( ResultConsumer r ) {
this.r=r
}
#Override
public void run() {
// some long task here, returns int value
r.sendResult(....)
}
}

Why is it important to make fields private when working with concurrency?

I'm reading Thinking in JAVA (Ed4, by Bruce Eckel), which says:
Note that it’s especially important to make fields private when
working with concurrency; otherwise the synchronized keyword cannot
prevent another task from accessing a field directly, and thus
producing collisions.
I am confused and finally get this demo:
public class SimpleSerial {
public static void main(String[] args) throws IOException {
ShareObject so = new ShareObject();
Thread thread1 = new Thread(new ThreadOperation(so, "add"));
Thread thread2 = new Thread(new ThreadOperation(so, "sub"));
thread1.setDaemon(true);
thread2.setDaemon(true);
thread1.start();
thread2.start();
System.out.println("Press Enter to stop");
System.in.read();
System.out.println("Now, a=" + so.a + " b=" + so.b);
}
}
class ThreadOperation implements Runnable {
private String operation;
private ShareObject so;
public ThreadOperation(ShareObject so, String oper) {
this.operation = oper;
this.so = so;
}
public void run() {
while (true) {
if (operation.equals("add")) {
so.add();
} else {
so.sub();
}
}
}
}
class ShareObject {
int a = 100;
int b = 100;
public synchronized void add() {
++a;
++b;
}
public synchronized void sub() {
--a;
--b;
}
}
Every time the values of a and b are different. So why?
The demo also mentioned if the thread sleep() for short time, i.e., re-write the run() method in ThreadOperation:
public void run() {
while (true) {
if (operation.equals("add")) {
so.add();
} else {
so.sub();
}
try {
TimeUnit.MILLISECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
then values of a and b are the same.
So again, Why? What happens behind sleep()?
With sleep() it becomes probable that the println() executes while the threads are sleeping. The program is still very not thread-safe.
You could fix it by adding a synchronized print() method to SharedObject eg:
public synchronized void print() {
System.out.println("Now, a=" + a + " b=" + b);
}
and calling that on the last line of main instead of the current unsynchronized accesses.

I want to know(print) state of one thread from another thread... can we do that?

I want to create two Threads.One to display something and after that it will go to Wait state.Then the second thread should start executing and it should print the state of the first thread(i.e waiting state) and after displaying it should notify and the first Thread should continue executing.
I have created a small program for you. Please check if it meets your requirement. We can beautify the code later. Please elaborate your requirements more, if it is not meeting your expectations.
public class Main {
public static void main(String[] args) {
MyThread1 th1 = new MyThread1();
MyThread2 th2 = new MyThread2();
//Allow thread 1 to run first
Shareable shareable = new Shareable();
shareable.threadToRun = th1.getName();
th1.setAnotherThread(th2);
th1.setShareable(shareable);
th2.setAnotherThread(th1);
th2.setShareable(shareable);
th1.start();
th2.start();
}
}
class Shareable {
volatile String threadToRun;
}
class MyThread1 extends Thread {
private Shareable shareable;
private Thread anotherThread;
#Override
public void run() {
synchronized (shareable) {
waitForTurn();
System.out.println(getName() + " I am doing first task. After that wait for next Thread to finish.");
shareable.threadToRun = anotherThread.getName();
shareable.notifyAll();
waitForTurn();
System.out.println(getName() + " I am doing next task now.");
}
}
private void waitForTurn(){
if(!shareable.threadToRun.equals(getName())){
try {
shareable.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void setShareable(Shareable shareable){
this.shareable = shareable;
}
public void setAnotherThread(Thread anotherThread){
this.anotherThread = anotherThread;
}
}
class MyThread2 extends Thread {
private Shareable shareable;
private Thread anotherThread;
#Override
public void run() {
synchronized (shareable) {
waitForTurn();
System.out.println(getName() + " I am doing task now. Another Thread " + anotherThread.getName() + " is in state " + anotherThread.getState());
shareable.threadToRun = anotherThread.getName();
shareable.notifyAll();
}
}
private void waitForTurn(){
if(!shareable.threadToRun.equals(getName())){
try {
shareable.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void setShareable(Shareable shareable){
this.shareable = shareable;
}
public void setAnotherThread(Thread anotherThread){
this.anotherThread = anotherThread;
}
}
Here is the output:
Thread-0 I am doing first task. After that wait for next Thread to finish.
Thread-1 I am doing task now. Another Thread Thread-0 is in state WAITING
Thread-0 I am doing next task now.

Class level lock for static variables in java

If i don't use any setters/getters in my java class X. When a thread A has class level lock of my class X. Can another thread B change my static variable directly ??
public class X {
Integer static_variable = 10;
public static void doNothing {
/* Do Nothing */
}
}
Lets say thread A has class level lock now. Can i do X.static_variable = 11 from another thread B?
I was writing a code to get deadlock in java.
public class A implements Runnable {
public static Integer as = 5;
static A a = new A();
static B b = new B();
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
Thread thread1 = new Thread(a);
Thread thread2 = new Thread(b);
thread1.setName("First");
thread2.setName("Second");
thread1.start();
thread2.start();
}
public void run() {
runme();
}
public static synchronized void runme() {
try {
System.out.println(Thread.currentThread().getName() + " has object a's key and waiting");
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName() + " Woke up from sleep");
System.out.println(Thread.currentThread().getName() + " wants b's Key");
B.bs = 10;
System.out.println(Thread.currentThread().getName() + " over");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class B implements Runnable {
public static Integer bs = 6;
public void run() {
runme();
}
public static synchronized void runme() {
try {
System.out.println(Thread.currentThread().getName() + " has object b's key and waiting");
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName() + " Woke up from sleep");
System.out.println(Thread.currentThread().getName() + " wants a's Key");
A.as = 10;
System.out.println(Thread.currentThread().getName() + " over");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
But getting below result:
Second has object b's key and waiting
First has object a's key and waiting
First Woke up from sleep
Second Woke up from sleep
Second wants a's Key
Second over
First wants b's Key
First over
Second thread is clearly editing the static variable of class A even when another thread holds the class level lock of class A
Yes you can. Unless you have a synchronized block around the variable changing code. If you don't use synchronization, other threads don't have to acquire the X.class's monitor before changing its static_variable.
Make the field private, and add a setter, make it synchronized, then you will not be able to change the field when another thread holds the lock for X.class

multiple threads performing different tasks

This is the first time I am writing multiple threaded program.
I have a doubt that multiple thread which I'l create will point to the same run method and perform the task written in run().
but I want different threads to perform different tasks
e.g 1 thread will insert into database other update and etc.
My question is how to create different threads that will perform different tasks
Create your threads that do different jobs:
public class Job1Thread extends Thread {
#Override
public void run() {
// Do job 1 here
}
}
public class Job2Thread extends Thread {
#Override
public void run() {
// Do job 2 here
}
}
Start your threads and they will work for you:
Job1Thread job1 = new Job1Thread();
Job2Thread job2 = new Job2Thread();
job1.start();
job2.start();
you can create different classes implementing Runnable with different jobs - just for start
You can run the run() method with your conditions (insert database, update, etc). While initializing your thread class, pass argument in class constructor, which will define what task this thread will do for you.
/* This program creates three different threads to perform three different tasks. Thread -1 prints A...Z, Thread-2 prints 1...100, Thread-3 prints 100-200. Very basic program for understanding multi-threading without creating different classes for different tasks */
class ThreadingClass implements Runnable {
private Thread t;
private String threadName;
ThreadingClass( String name) {
threadName = name;
System.out.println("Creating " + threadName );
}
public void run() {
System.out.println("Running " + threadName );
if( threadName == "Thread-1" ){
this.printAlpha();
}
else if( threadName == "Thread-2" ){
this.printOneToHundred();
}
else{
this.printHundredMore();
}
}
public void printAlpha(){
for(int i=65; i<=90; i++)
{
char x = (char)i;
System.out.println("RunnableDemo: " + threadName + ", " + x);
}
}
public void printOneToHundred(){
for(int i=1; i<=100; i++)
{
System.out.println("RunnableDemo: " + threadName + ", " + i);
}
}
public void printHundredMore(){
for(int i=100; i<=200; i++)
{
System.out.println("RunnableDemo: " + threadName + ", " + i);
}
}
public void start () {
System.out.println("Starting " + threadName );
if (t == null) {
t = new Thread (this);
t.start ();
t.setName(threadName);
}
}
}
public class MultiTasking {
public static void main(String args[]) {
ThreadingClass R1 = new ThreadingClass ( "Thread-1");
ThreadingClass R2 = new ThreadingClass ( "Thread-2");
ThreadingClass R3 = new ThreadingClass ( "Thread-3");
R1.start();
R2.start();
R3.start();
}
}
You can use inner class for this. Like below
class first implements Runnable
{
public void run(){
System.out.println("hello by tobj");
}
public static void main(String args[]){
first obj=new first();
Thread tobj =new Thread(obj);
tobj.start();
Thread t2 =new Thread(obj)
{
public void run()
{
System.out.println("hello by t2");
}
};
Thread t = new Thread(obj)
{
public void run()
{
System.out.println("hello by t");
}
};
t.start();
t2.start();
}
}

Categories