简体   繁体   English

Java中的线程同步

[英]Thread Synchronization in java

Why I'm not able to achieve Synchronization on this below piece of program: 为什么我无法在下面的程序上实现同步:

class P
{

synchronized void pp(String s)
    {
        System.out.println (s);
    }
}

class threadA extends Thread 
{
    P ob;
    String s;
    threadA (P ob, String s)
    {
        this.ob = ob;
        this.s = s;
    }
    public void run ()
    {
        for (int i=1;i<=5;++i)
        {
        ob.pp (s);
        try
        {
            Thread.sleep (1000);
        }
        catch (Exception e) {}
        }
    }
}


class gain 
{
    public static void main(String[] args) {
        P ob = new P ();
        threadA a = new threadA (ob,"Hello User");
        threadA b = new threadA (ob,"Bye User");
        a.start();
        b.start();
    }
}

OP: OP:

Hello User 你好用户

Bye User 再见用户

Hello User 你好用户

Bye User 再见用户

Bye User 再见用户

... ...

I want OP in the form of: 我想要以下形式的OP:

Hello User 你好用户

Hello User 你好用户

Hello User.. 您好用户。

Bye User 再见用户

Bye User 再见用户

Bye User.. 再见用户

or my concept of synchronization is wrong? 还是我的同步概念错了?

You cannot do such synchronization from P class. 您不能从P类进行此类同步。 What happens now is that any calls to pp() is blocked if another thread is currently executing the method. 现在发生的是,如果另一个线程当前正在执行该方法,则对pp()所有调用都将被阻止。 As long as the method ends (which is quick if you are just going to print things to the console), the next thread would be allowed to enter the method. 只要方法结​​束(如果您只是要将内容打印到控制台,这将很快),则将允许下一个线程进入该方法。

What you are trying to achieve is not possible, unless both the threads are aware of each other and communicate with each other. 除非两个线程都相互了解并相互通信,否则您将无法实现目标。 In other words, when the first thread finishes what it needs to do, it should explicitly inform the second thread to start. 换句话说,当第一个线程完成其所需的操作时,它应明确通知第二个线程开始。 This is effectively executing sequentially, instead of parallelly. 这实际上是顺序执行的,而不是并行执行的。

Update 更新资料

You wanted to visualize what is happening so I'll do it here. 您想可视化正在发生的事情,所以我在这里做。

  1. You created 2 threads. 您创建了2个线程。
  2. You start the first thread. 您启动第一个线程。
  3. The first thread starts to run, while some time later the second starts to run as well. 第一个线程开始运行,而一段时间后,第二个线程也开始运行。
  4. When your first thread runs, it goes to the for loop. 当您的第一个线程运行时,它进入for循环。 Then it calls P.pp() . 然后调用P.pp()
  5. When P.pp() is called from first thread, it locks the P object. 从第一个线程调用P.pp() ,它将锁定 P对象。
  6. Since the method is so short, it is going to exit very quickly. 由于该方法很短,因此将很快退出。
  7. When the method exits, it releases the lock on P . 方法退出时,它将释放对P的锁定。
  8. If your second thread reaches the synchronize block before the first thread exits, it will wait (blocked). 如果您的第二个线程在第一个线程退出之前到达了synchronize块,它将等待(阻塞)。
  9. When the first thread exits, the second thread enters as the first thread releases the lock. 当第一个线程退出时,第二个线程进入,因为第一个线程释放了锁。
  10. The first thread returns to the loop and try to call P.pp() again. 第一个线程返回循环并尝试再次调用P.pp()
  11. This will continue, depending on which thread is faster, the order of execution would be different. 这将继续,具体取决于哪个线程更快,执行的顺序会有所不同。

Synchronized keyword means that two threads on that code block have to respect the order they tried to access that block code. Synchronized关键字意味着该代码块上的两个线程必须遵守它们尝试访问该块代码的顺序。 It doesn't mean that the execution flow is serialized. 这并不意味着执行流程已序列化。

To have what you want try to put the for inside the synchronized block... 要拥有想要的内容,请尝试将for放在同步块中...

You should try something like this 你应该尝试这样的事情

class P
{

void pp(String s)
    {
        System.out.println (s);
    }
}

class threadA extends Thread 
{
    P ob;
    String s;
    threadA (P ob, String s)
    {
        this.ob = ob;
        this.s = s;
    }
    public void run ()
    {
        for (int i=1;i<=5;++i)
        {
            synchronized(ob)
            {
               ob.pp (s);
                try
                {
                    Thread.sleep (10);
                }
                catch (Exception e) {}
            }


        }
    }
}


public class gain 
{
    public static void main(String[] args) {
        P ob = new P ();
        threadA a = new threadA (ob,"Hello User");
        threadA b = new threadA (ob,"Bye User");
        a.start();
        b.start();
    }
}

ie while sleeping keep thread synchronized so that you get required output or else you are not sure which thread might come up first after sleep. 即,在睡眠时保持线程同步,以便获得所需的输出,否则您不确定睡眠后哪个线程可能首先出现。 See this 看到这个

can u explain me the flow of control of my program? 您能解释一下我程序的控制流程吗?

"Hello" starts and run through the loop until it reaches the synchronized method “ Hello”启动并循环运行,直到达到synchronized方法

"Bye" does the same. “再见”也一样。

"Hello" is the first to acquire the lock. “ Hello”是第一个获得锁的人。

"Bye" blocks waiting for the lock. “再见”阻止等待锁。

"Hello" executes the method and releases the lock. “ Hello”执行该方法并释放锁。

"Bye" can now acquire the lock and "Hello" has released it “ Bye”现在可以获取该锁,“ Hello”已释放它

"Bye" can now execute the method, and releases the lock as "Hello" did. “ Bye”现在可以执行该方法,并像“ Hello”一样释放该锁。

what can I do so that hello after executing the method goes to blocked pool and also doesn't leaves the lock for bye to acquire it 我该怎么办,以便在执行该方法后打招呼进入阻塞的池,并且也不会留下锁让再见

Hold the lock, and don't release it if you want to retain it. 握住锁,如果要保留它,请勿释放它。

public void run() {
    synchronized(ob); { // hold the lock the whole time
        for (int i = 1; i <= 5; ++i) {
            ob.pp (s);
            try { Thread.sleep(1000); } catch (Exception e) {}
        }
    } // releases the lock here.
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM