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

How to do inter thread communication inside static synchronized block

我有一个关于静态同步方法和 class 级别锁定的问题。 有人可以帮我解释一下这个例子吗:

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();
    }
}

问题:

当线程 t1 处于循环中间(在 printTest() 内)并且我想让它停止执行并将控制权转移到线程 t2。 有什么办法吗?

由于我们处理 class 级锁,我相信我们不能在这里使用对象级 wait()notify() 方法来释放对象级锁。但是在 class 级锁的情况下,如何释放它并将控制权交给其他一些等待线程?

我们如何通知正在等待线程 1 在执行过程中持有的 class 级锁的第二个线程?

来自您的评论:

There is one thread (t2)waiting on a class level lock held by another thread (t1). So is it possible for t1 thread to notify thread t2 before t1 exits from the static synchronized method.

是的,类是对象,调用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 ) {
      }

   }
}

interrupt() 可根据您的要求在此处使用。

如果您的要求将来发生变化,并且需要在第二个线程之后执行第一个线程,则删除 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()

我尽量避免说 "class level" 或 "object level." 每当您使用 synchronized 时,您都在同步某个对象。记住:Test.class一个对象:它是包含描述Testclass的所有运行时间信息的对象.

当你说 "class level locking" 时,你真正谈论的是在 全局单例 对象(class 对象)上同步,而不是到 "instance level locking" 其中可能有许多不同的 class 实例可以独立 synchronized.

I want to make it stop the execution and transfer the control to thread t2.

这不是思考线程的非常有用的方法。您通常不希望程序中的线程等待轮到它执行某些任务:您希望它等待自己的任务。总会有 一些 需要线程相互协调和通信,但是你越能够让每个线程去做自己的事情,你就会更好地利用其中

与其想 "transferring control" 从一个线程到另一个线程,不如让每个线程始终控制自己的事情。

How do we notify a second thread which is waiting for a [...] lock?

没有任何东西 可以释放等待进入 synchronized 块的线程。这是 synchronized 的局限性之一,这也是为什么任何线程在 synchronized 块中停留的时间超过更新几个字段所花费的时间都是一个坏主意的原因之一。

I want to make it stop the execution

引起循环线程注意的最简单方法是让线程在每次循环时检查 volatile boolean 变量的值。

volatile boolean timeToStop = false;

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

然后,任何其他线程都可以设置 timeToStop=true; 以引起第一个线程的注意。