简体   繁体   English

如何在静态同步块内进行线程间通信

[英]How to do inter thread communication inside static synchronized block

I have a question regarding static synchronized methods and class level locking. 我有一个关于静态同步方法和类级别锁定的问题。 Can someone please help me in explaining this example: 有人可以帮我解释一下这个例子:

class Test
{
    synchronized static void printTest(int n)
    {
        for (int i = 1; i <= 10; i++) {
            System.out.println(n * i);
            try {
                Thread.sleep(400);
            } catch (Exception ignored) {}
        }
    } 
}  

class MyThread1 extends Thread
{
    public void run()
    {
        Test.printTest(1);
    }
}

class MyThread2 extends Thread
{
    public void run()
    {
        Test.printTest(10);
    }
}

public class TestSynchronization
{
    public static void main(String[] args)
    {
        MyThread1 t1 = new MyThread1();
        MyThread2 t2 = new MyThread2();
        t1.start();
        t2.start();
    }
}

Question: 题:

When thread t1 is in the middle of loop (inside printTest() ) and I want to make it stop the execution and transfer the control to thread t2 . 当线程t1在循环中间(在printTest()内部)时,我要使其停止执行,并将控制权转移到线程t2 Is there any way to do it? 有什么办法吗?

Since we deal with class level lock I believe we cannot use object level wait() and notify() methods here which would release the object level lock. 由于我们处理类级别的锁,我相信我们不能在此处使用对象级别的wait()notify()方法来释放对象级别的锁。 But in case of class level lock, how to release it and give the control to some other waiting thread? 但是在类级别锁的情况下,如何释放它并将控制权交给其他等待线程?

How do we notify a second thread which is waiting for a class level lock held by thread 1 in the middle of execution? 我们如何通知第二个线程在执行过程中等待线程1持有的类级别锁?

interrupt() can be used here for your requirement. 您可以在此处使用interrupt()来满足您的要求。

If your requirement gets change in future and execution of first thread is required after the second thread then remove if(Thread.interrupted()) inside printTest 如果将来您的需求发生变化,并且在第二个线程之后需要执行第一个线程,则在printTest删除if(Thread.interrupted())

 class Test {
    synchronized static void printTest(int n) {
        for (int i = 1; i <= 10; i++) {
            if(Thread.interrupted())
                break;
            System.out.println(n * i);
            try {
                Thread.sleep(400);
            } catch (Exception e) {
            }
        }
    }
 }

 class MyThread1 extends Thread {
    public void run() {
        Test.printTest(1);
    }
 }

 class MyThread2 extends Thread {
    public void run() {
        Test.printTest(10);
    }
 }

 public class TestSynchronization {
    public static void main(String t[]) throws InterruptedException {
        MyThread1 t1 = new MyThread1();
        MyThread2 t2 = new MyThread2();
        t1.start();
        t2.start();

        t1.interrupt();
        t1.join();
    }

 }

Since we deal with class level lock I believe we cannot use object level wait() and notify() 因为我们处理类级别的锁,所以我相信我们不能使用对象级别的wait()notify()

I try to avoid saying "class level" or "object level." 我尽量避免说“类级别”或“对象级别”。 Whenever you use synchronized you are synchronizing on some object. 每当您使用synchronized您就在某个对象上进行同步。 Remember: Test.class is an object: It's the object that contains all of the run-time information that describes the Test class. 请记住: Test.class 一个对象:它是包含描述Test类的所有运行时信息的对象。

When you say "class level locking", what you're really talking about is synchronizing on a global singleton object (the class object), as opposed to "instance level locking" where there may be many different instances of the class that can be independently synchronized . 当您说“类级别锁定”时,您真正要说的是在全局单例对象(类对象)上进行同步,而不是“实例级别锁定”,在该实例中可能存在许多不同的类实例。独立synchronized

I want to make it stop the execution and transfer the control to thread t2. 我想让它停止执行并将控件转移到线程t2。

That's not a very useful way to think about threads. 这不是考虑线程的非常有用的方法。 You generally don't want a thread in your program to wait for its turn to work on some task: You want it to wait for a task of its own. 通常,您不希望程序中的线程等待轮流执行某些任务:您希望它等待自己的任务。 There will always be some need for threads to coordinate and communicate with each other, but the more you are able to let each thread go off to do its own thing, the better use you will make of them. 总是会有一些需要线程协调和相互沟通,但是你越能够让每个线程走下车做自己的事,更好地利用你会让他们的。

Rather than think of "transferring control" from one thread to another, you want each thread to be in control of its own thing, all the time. 您希望每个线程始终控制自己的事物,而不是想将控制权从一个线程转移到另一个线程。

How do we notify a second thread which is waiting for a [...] lock? 我们如何通知正在等待锁定的第二个线程?

There is nothing that can release a thread from waiting to enter a synchronized block. 没有什么可以使线程从等待进入synchronized块的状态中释放出来的。 That's one of the limitations of synchronized , and that's one of the reasons why it's a bad idea for any thread to ever stay in a synchronized block for any longer than it takes to update a few fields. 这是局限性的一个synchronized ,这就是为什么这是一个坏主意,任何线程永远留在的原因之一synchronized块不再比需要更新的几个领域。

I want to make it stop the execution 我想让它停止执行

The simplest way to get the attention of a looping thread is to have the thread check the value of a volatile boolean variable each time around the loop. 引起循环线程注意的最简单方法是让该线程在循环过程中每次都检查volatile boolean变量的值。

volatile boolean timeToStop = false;

MyType myMethod(...) {
    while (! timeToStop) {
        ...
    }
}

Then, any other thread can set timeToStop=true; 然后,任何其他线程都可以设置timeToStop=true; in order to get the first thread's attention. 为了引起第一线程的注意。

From your comment: 根据您的评论:

There is one thread (t2)waiting on a class level lock held by another thread (t1). 有一个线程(t2)等待另一个线程(t1)持有的类级别锁。 So is it possible for t1 thread to notify thread t2 before t1 exits from the static synchronized method. 因此,t1线程有可能在t1从静态同步方法退出之前通知线程t2。

Yes, classes are objects, just call notify() . 是的,类是对象,只需调用notify()

class Test
{

   synchronized static void printTest( int n )
   {
      for( int i = 1; i <= 10; i++ ) {
         System.out.println( n * i );
      }
      try {
        Test.class.notify();     // just use a class literal
      } catch( Exception ignored ) {
      }

   }
}

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

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