Home > OS >  Thread synchronizing - almost same expressions but different result
Thread synchronizing - almost same expressions but different result

Time:05-18

public class MythreadM {

    public static void main(String[] args) {
        // TODO Auto-generated method stub

        Msg m = new Msg();
        Mythread thread1 = new Mythread(m);
        thread1.start();
        
        Mythread thread2 = new Mythread(m);
        thread2.start();
        
        Mythread thread3 = new Mythread(m);
        thread3.start();
    }

}
class Mythread extends Thread
{
    private Msg m;
    
    Mythread(Msg m)
    {
        this.m = m;
    }
    public void run() 
    {
        System.out.println(getName() "start");
        for(int i=0; i<300; i  )
        {
            processMsg(i);
        }
    }
    synchronized void processMsg(int i) // here starts question.
    {
//      synchronized(m)
        {
            m.write(getName() " message " i);
            try {
                sleep(1);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            m.print();
        }   
    }
    
}

class Msg
{
    String str = "def message";
    
    void print()
    {
        System.out.println(str " " System.currentTimeMillis());
    }
    void write(String str)
    {
        this.str = str;
    }
    
}

Full code above-----------------

and following 3 codes with almost same expressions.

<< code 1 >> : synchronized(m) {}

    void processMsg(int i)
    {
        synchronized(m)
        {
            m.write(getName() " message " i);
            try {
                sleep(1);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            m.print();
        }   
    }

<< code 2 >> : synchronized void processMsg(int i)

    synchronized void processMsg(int i)
    {

        {
            m.write(getName() " message " i);
            try {
                sleep(1);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            m.print();
        }   
    }

<< code 3 >> : synchronized void processMsg(int i) without inner{}

    synchronized void processMsg(int i)
    {


            m.write(getName() " message " i);
            try {
                sleep(1);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            m.print();

    }

It looks these 3 codes mean same just with different expressions but these 3 codes acts totally different.
Even < code 2 > is not synchronized, prints non-synchronized results.
Why is this happening?
And what's the purpose of the sleep(1); ?
Thanks in advance.

CodePudding user response:

It seems like this is example code to demonstrate that when synchronize on an object common to all threads (m), only one thread at a time can use it, as opposed to when you synchronize a method in the thread, which doesn't do anything because each thread is getting it's own lock.

To your second question, the meaning of sleep(1) is that the current thread should wait for at least 1 millisecond before proceeding.

Finally, in my experience, when you have several threads that are after the same resource (especially a (Print)stream like System.out) that the best way to solve this is to have a message queue to ynchronize the messages going out.

CodePudding user response:

"Even < code 2 > is not synchronized, prints non-synchronized results. Why is this happening?"

When you synchronize on m, it's an instance variable. Each MyThread gets its own copy. Thus it basically does no synchronization at all, because each thread can always acquire the lock.

The same goes for putting synchronized on the method processingMsg(). These are three separate objects you make, and only the object is synchronized. If you want three objects to share a lock, you need a static lock or something similar.

  • Related