有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java是挂起、恢复和停止线程以及多个实例上的多个线程的现代方式吗?

在阅读了大量关于网络线程的资料后,在Herbert Schildt的书《完整参考Java》的帮助下,我知道了这一点

synchronized only prevents multiple threads from simultaneously executing the method in the same
instance. I said... in the same instance.

When one thread is executing a synchronized method for an object, all other threads that invoke synchronized methods for the same object block (suspend execution) until the first thread is done with the object. Notice ... in the same instance(object).

Thirdly, from oracle docs,
when a synchronized method exits, it automatically establishes a happens-before RELATIONSHIP with any subsequent invocation of a synchronized method for the same object. This guarantees that
changes to the state of the object are visible to all threads. This also involves working on the same object with multiple threads.

但是当遇到多个线程在同一个类的不同实例上工作的情况时,我会变得非常困惑,无法理解发生了什么以及是如何发生的

考虑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.

我的理解是: 有三条线。除主线程外,2正在处理同一类的2个实例

主线程进入睡眠状态10秒。 在这段时间内,另外两个可以通过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会考虑这个变化吗

挂起线程一//这会被打印出来

主线程再次进入睡眠状态10秒。 处理ob1的线程没有产生任何输出。为什么?(因为前面提到的更改已被考虑在内,这就是为什么在完成循环后,wait()会挂起该线程。我说得对吗?)

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

ob1调用同步的方法:myresume(),在其中进行更改

将suspendFlag设置为false和

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

这里有点困惑:线程(在ob1上)是如何恢复自身的(我的意思是,尽管我不太清楚它是如何被挂起的,但为什么仅仅改变标志就可以了。)

正在恢复线程一//将被打印。 由于o/p如下图所示,线程明显恢复(恢复)

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

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

还有一个问题:

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


共 (1) 个答案

  1. # 1 楼答案

    ob1 calls it mysuspend() which changes the suspendFlag to true. Confused here: will this change be taken into consideration by thread working ob1.

    Main thread goes to sleep again for 10 seconds. the thread working on ob1 didn't produce any output. WHY? (Because the change previously mentioned was taken into consideration and that's why after going through the loop, wait() suspends this thread. Am I correct?).

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

    issues a notify() // notification to the other thread working on the other object.

    否。java.lang.Object.notify()唤醒了一个线程,该线程正在等待这个对象的监视器。注意关键字this。由于ob1只有一个线程作用于它,发出wait()的线程将被通知,而不是处理ob2的线程,它们是处理同一类型的different threads的两个线程

    How was the thread (on ob1) able to resurrect itself(I mean how come by just changing the flag even though i am not too clear how it got suspended.)

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

    When one thread is executing a synchronized method for an object, does all other threads that invoke synchronized methods for the other object block (suspend execution) until the first thread is done with the object. I said the other object?

    不会。只有在特定实例上工作的线程才会受到影响。如果你想这样

    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