【问题标题】:The modern way of suspending, resuming, and stopping threads and multiple threads on multiple instances?在多个实例上挂起、恢复和停止线程和多个线程的现代方式?
【发布时间】:2014-10-05 21:39:40
【问题描述】:

在阅读了网上关于线程的大量资料后,在 Herbert Schildt 的书 The Complete Reference Java Java 的帮助下,我知道了

同步只防止多个线程同时执行同一个方法
实例。我说……在同样的情况下。

当一个线程为一个对象执行同步方法时,调用的所有其他线程 相同对象块的同步方法(暂停执行),直到第一个线程完成 与对象。注意...在同一个实例(对象)中。

第三,来自 oracle 文档,
当同步方法退出时,它会自动建立一个发生前的关系 对同一对象的同步方法的任何后续调用。这保证了
对象状态的更改对所有线程都是可见的。这还涉及在 具有多个线程的同一对象。

但是当出现多个线程处理同一个类的不同实例的情况时,我总体上感到困惑,无法弄清楚发生了什么以及它是如何发生的?

考虑 Herbert Schildt 书中给出的示例:以现代方式暂停和恢复线程。

class NewThread implements Runnable {

String name; // name of thread
Thread t;
boolean suspendFlag;

NewThread(String threadname) {
    name = threadname;
    t = new Thread(this, name);
    System.out.println("New thread: " + t);
    suspendFlag = false;
    t.start(); // Start the thread
}

// This is the entry point for thread.
public void run() {
    try {
        for (int i = 15; i > 0; i--) {
            System.out.println(name + ": " + i);
            Thread.sleep(2000);
            synchronized (this) {
                while (suspendFlag) {
                    wait();
                }
            }
        }
    } catch (InterruptedException e) {
        System.out.println(name + " interrupted.");
    }
    System.out.println(name + " exiting.");
}

void mysuspend() {
    suspendFlag = true;
}

synchronized void myresume() {
    suspendFlag = false;
    notify();
}
}

主线程:

class SuspendResume {

public static void main(String args[]) {

    NewThread ob1 = new NewThread("One");
    NewThread ob2 = new NewThread("Two");

    try {
        Thread.sleep(10000);
        ob1.mysuspend();
        System.out.println("Suspending thread One");

        Thread.sleep(10000);
        ob1.myresume();
        System.out.println("Resuming thread One");

        ob2.mysuspend();
        System.out.println("Suspending thread Two");
        Thread.sleep(10000);

        ob2.myresume();
        System.out.println("Resuming thread Two");
    } catch (InterruptedException e) {
        System.out.println("Main thread Interrupted");
    }
    // wait for threads to finish
    try {
        System.out.println("Waiting for threads to finish.");
        ob1.t.join();
        ob2.t.join();
    } catch (InterruptedException e) {
        System.out.println("Main thread Interrupted");
    }

    System.out.println("Main thread exiting.");
}

}

输出如下:

New thread: Thread[One,5,main]
New thread: Thread[Two,5,main]
One: 15
Two: 15
One: 14
Two: 14
Two: 13
One: 13
Two: 12
One: 12
Two: 11
One: 11
Suspending thread One
Two: 10
Two: 9
Two: 8
Two: 7
Two: 6
Resuming thread One
Suspending thread Two
One: 10
One: 9
One: 8
One: 7
One: 6
Resuming thread Two
Waiting for threads to finish.
Two: 5
One: 5
Two: 4
One: 4
Two: 3
One: 3
Two: 2
One: 2
Two: 1
One: 1
Two exiting.
One exiting.
Main thread exiting.

我的理解: 有3个线程。除了主线程之外,2 个正在处理同一类的 2 个实例。

主线程休眠 10 秒。 在此期间,另外 2 个能够通过 for 循环进行 5 次。(因为他们也每个人都睡了 2 秒。) 在此间隔期间标志为假,因此他们没有进入 while 循环。此间隔期间的 o/p 是:

One: 15
Two: 15
One: 14
Two: 14
Two: 13
One: 13
Two: 12
One: 12
Two: 11
One: 11

主线程唤醒。

ob1 将其称为 mysuspend(),它将suspendFlag 更改为true。 在这里感到困惑:线程工作 ob1 是否会考虑此更改。

暂停线程一 //this 得到打印。

主线程再次休眠 10 秒。 在 ob1 上工作的线程没有产生任何输出。为什么? (因为前面提到的变化已经被考虑在内,这就是为什么在循环之后,wait() 会挂起这个线程。我说的对吗?)。

Two: 10
Two: 9
Two: 8
Two: 7
Two: 6

ob1 调用同步方法:myresume() 在其中发生变化

suspendFlag 为 false 和

向处理另一个对象的另一个线程发出一个 notify() // 通知。 我确定通知命令从等待集中任意选择一个线程并将其标记为最终复活。并且锁还在。

在这里感到困惑:线程(在 ob1 上)如何能够自我复活(我的意思是即使我不太清楚它是如何被挂起的,也只是通过更改标志来实现。)

恢复线程一 // 被打印。 线程显然已经复活(恢复),因为 o/p 如下所示。

One: 10
One: 9
One: 8
One: 7
One: 6

同时,另一个线程被挂起,同样的事情发生了。

还有一个问题:

当一个线程为一个对象执行同步方法时,所有其他调用另一个对象的同步方法的线程是否会阻塞(暂停执行),直到第一个线程处理完该对象。我说的是另一个对象?

【问题讨论】:

  • 我不太了解 Java 或其线程要求,但我希望 void mysuspend() 方法也需要为 synchronized

标签: java multithreading synchronized


【解决方案1】:

ob1 将其称为 mysuspend(),这会将 suspendFlag 更改为 true。在这里感到困惑:线程是否会考虑此更改 工作ob1。

主线程再次休眠 10 秒。在 ob1 上工作的线程没有产生任何输出。为什么? (因为之前的改动 提到的被考虑在内,这就是为什么去之后 通过循环,wait() 挂起这个线程。我说的对吗?)。

是的。由于可运行实例'ob1'state 已更改,并且只会影响在可运行实例'ob1' 上工作的线程。

向处理另一个对象的另一个线程发出一个 notify() // 通知。

没有。 java.lang.Object.notify() 唤醒正在 this 对象的监视器上等待的单个线程。注意关键字this。由于ob1只有一个线程作用于它,所以发出wait()的线程将被通知,而不是在ob2上工作的线程,它们是两个different threads在同一类型的two different runnable instances上工作。

线程(在 ob1 上)如何能够自我复活(我的意思是即使我不太清楚它是如何得到的,也只是通过更改标志来实现 暂停。)

ob1绑定的线程可以监听ob1的状态变化。 ob2绑定的线程可以监听ob2的状态变化。

当一个线程为一个对象执行同步方法时,是否所有其他线程为另一个调用同步方法 对象块(暂停执行),直到第一个线程完成 物体。我说的是另一个对象?

没有。只有在该特定实例上工作的线程才会受到影响。如果您希望这种情况发生,

NewThread obj = new NewThread(); // single runnable instance
Thread ob1 = new Thread(obj); // two different threads sharing the same instance
Thread ob2 = new Thread(obj);

这样,线程ob1ob2 可以使用objwait()notify() 方法相互共享obj 实例和communicate

如果您正在寻找跨实例同步线程,请查看:this

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-22
    • 1970-01-01
    • 2013-03-08
    • 1970-01-01
    • 2012-05-20
    • 2011-07-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多