在网上阅读了大量有关线程的内容后,在Herbert Schildt的书“完全参考Java”的帮助下,我知道
synchronized仅防止多个线程同时执行同一方法 实例。我说......在同一个例子中。
当一个线程正在为对象执行synchronized方法时,调用所有其他线程 同一个对象块的同步方法(暂停执行)直到第一个线程完成 与对象。注意......在同一个实例(对象)中。
第三,来自oracle docs,
当一个synchronized方法退出时,它会自动建立一个发生在之前的RELATIONSHIP 任何后续调用同一对象的同步方法。这保证了 所有线程都可以看到对象状态的更改。这也涉及到工作 具有多个线程的相同对象。
但当情况出现在多个线程处理同一个类的不同实例时,我总体上感到困惑,无法弄清楚发生了什么以及它是如何发生的?
考虑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秒钟。 在这段时间内,另外两个人可以通过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会考虑这种变化。
暂停线程1 //这会打印。
主线程再次进入睡眠状态10秒钟。 在ob1上工作的线程没有产生任何输出。为什么? (因为前面提到的更改被考虑在内,这就是为什么在循环之后,wait()会暂停这个线程。我是否正确?)。
Two: 10
Two: 9
Two: 8
Two: 7
Two: 6
ob1调用synchronized方法:myresume(),在其中更改
suspendFlag为false和
向另一个处理另一个对象的线程发出notify()//通知。 我肯定知道一个通知命令从等待集中任意选择一个线程并将其标记为最终复活。并且锁仍在使用它。
在这里感到困惑:线程(在ob1上)如何能够自我复活(我的意思是如何改变旗帜,即使我不太清楚它是如何被暂停的。)
恢复线程一个//被打印。 因为o / p在那里,所以线程显然已经复活(恢复)。
One: 10
One: 9
One: 8
One: 7
One: 6
在同一时间,另一个线程被暂停,同样的事情发生了。
还有一个问题:
当一个线程正在为对象执行synchronized方法时,所有其他线程都会调用另一个对象的同步方法阻塞(暂停执行),直到第一个线程完成对象为止。我说了另一个对象?
答案 0 :(得分:1)
ob1将其命名为mysuspend(),将suspendFlag更改为true。在这里感到困惑:线程会考虑这种变化 工作ob1。
主线程再次进入睡眠状态10秒钟。在ob1上工作的线程没有产生任何输出。为什么? (因为此前有变化 提到被考虑,这就是为什么去了之后 通过循环,wait()挂起这个线程。我纠正了吗?)。
是。由于可运行实例state
的{{1}}已更改,并且仅影响在可运行实例'ob1'
上运行的线程。
向另一个处理另一个对象的线程发出notify()//通知。
没有。 'ob1'
唤醒正在此对象的监视器上的单个线程。请注意关键字此。由于java.lang.Object.notify()
只有一个线程对其进行操作,因此将通知发布ob1
的线程,而不是处理wait()
的线程,它们是两个ob2
正在处理{ {1}}属于同一类型。
线程(在ob1上)如何能够自我复活(我的意思是如何改变旗帜,即使我不太清楚它是如何得到的 暂停。)
绑定到different threads
的线程可以监视two different runnable instances
状态的变化。绑定到ob1
的线程可以监视ob1
状态的更改。
当一个线程正在为一个对象执行一个synchronized方法时,所有其他线程都会为另一个调用同步方法 对象块(暂停执行),直到第一个线程完成 物体。我说了另一个对象?
没有。只有处理该特定实例的线程才会受到影响。如果你想要那样,
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);
可以使用ob1
和ob2
obj
方法相互共享communicate
实例和wait()
{1}}。
如果您正在寻找跨实例的线程同步,请查看:this。