user414967
user414967

Reputation: 5325

java thread synchronization issue

Would like to post some doubts regarding Thread synchronization. I understood the concepts of synchronization. But when I implemented a sample java program through multithreading, I could not achieve the result what I want. But finally I could achieve the result by changing one line of code.But I would like to know whats wrong with the below code.

Here when I use synchronized block, synchnonized(SharedResource.class) I could achieve the result what I want. why it is not working for synchonized method and synchronized(this) block?

public class SharedResource {   
    public  synchronized void access(String name){      

            System.out.println(name+" :accessed shared resoure");
            System.out.println(name+" doing his job: ");
            for(int i = 0; i < 5;i++){
                try {
                    System.out.println(name+": "+ i);
                    Thread.sleep(500);
                } catch (InterruptedException e) {              
                    e.printStackTrace();
                }
            }
            System.out.println(name+" :finished doing his job..");

        }
}


public class SharedAccessThread implements Runnable {

    private String name ;
    public SharedAccessThread(String name) {
            this.name = name ;
    }
    @Override
    public void run() {
        SharedResource resource = new SharedResource();
        resource.access(Thread.currentThread().getName());

    }

}



public class MultiThreading {

    public static void main(String[] args) {

        SharedAccessThread thread = new SharedAccessThread(Thread.currentThread().getName());

        Thread t1 = new Thread(thread);
        t1.setName("A");
        Thread t2 = new Thread(thread);
        t2.setName("b");
        Thread t3 = new Thread(thread);
        t3.setName("C");

        t1.start();
        t2.start();
        t3.start();

    }

}

   The expected out put is below:

A :accessed shared resoure
A doing his job: 
A: 0
A: 1
A: 2
A: 3
A: 4
A :finished doing his job..
C :accessed shared resoure
C doing his job: 
C: 0
C: 1
C: 2
C: 3
C: 4
C :finished doing his job..
b :accessed shared resoure
b doing his job: 
b: 0
b: 1
b: 2
b: 3
b: 4
b :finished doing his job..

But it gives in a shuffled manner. That means A accessed shared resource..B doing his job...,etc which I dont want.

Upvotes: 0

Views: 372

Answers (2)

Tudor
Tudor

Reputation: 62439

The problem is that you are creating a new SharedResource inside each thread:

@Override
public void run() {
    SharedResource resource = new SharedResource();
    resource.access(Thread.currentThread().getName());

}

Therefore, synchronizing on this or on the method itself (which is the same as synchronizing on this) causes each thread to see a different lock and so it has no effect.

Synchronizing on the class itself works because it functions as a global lock, since the class itself is the same for all threads.

To be able to synchronize on this you should make the resource a static member for example:

public class SharedAccessThread implements Runnable {

    private String name;
    private static SharedResource resource = new SharedResource();

    public SharedAccessThread(String name) {
            this.name = name ;
    }
    @Override
    public void run() {          
        resource.access(Thread.currentThread().getName());   
    }    
}

This guarantees that all your threads see the same instance of SharedResource.

Upvotes: 4

Sam
Sam

Reputation: 6890

Your code not need to synchronization. Synchronization important in positions such as : Global member and any thread change its values, but in your sample dont any mutual exclusion. In java any thread has own Thread Context consist of local variable , input parameter and etc. In your code, any thread has a SharedResource instance and call access method of it, so don't worry for thread-safety issue.

Upvotes: -1

Related Questions