Java 为什么同步功能不阻止进入?(爪哇)
我有两个类,我想用它们创建一个死锁。 我试图创建两个相互读取的同步函数,因此该过程将被卡住。 但是,这些函数并没有被卡住,而是继续相互调用。 我不明白为什么会发生这种情况,synchronized关键字应该在同一个函数中有另一个进程时阻止该进程进入该函数Java 为什么同步功能不阻止进入?(爪哇),java,Java,我有两个类,我想用它们创建一个死锁。 我试图创建两个相互读取的同步函数,因此该过程将被卡住。 但是,这些函数并没有被卡住,而是继续相互调用。 我不明白为什么会发生这种情况,synchronized关键字应该在同一个函数中有另一个进程时阻止该进程进入该函数 MyRun: public class MyRun extends Thread{ MyRun1 myRun1; MyRun(){ myRun1 = new MyRun1(this); } public synchronized
MyRun:
public class MyRun extends Thread{
MyRun1 myRun1;
MyRun(){
myRun1 = new MyRun1(this);
}
public synchronized boolean f(){
System.out.println("MyRun.f()");
while (!myRun1.f()){
}
return true;
}
}
public class MyRun1 extends Thread {
MyRun myRun;
MyRun1(MyRun myRun){
this.myRun = myRun;
}
public synchronized boolean f(){
System.out.println("MyRun1.f()");
while (!myRun.f()){}
return true;
}
}
public static void main(String[] args){
MyRun myRun = new MyRun();
myRun.f();
}
MyRun.f()
MyRun1.f()
MyRun.f()
MyRun1.f()
.
.
.
.
Exception in thread "main" java.lang.StackOverflowError
MyRun2:
public class MyRun extends Thread{
MyRun1 myRun1;
MyRun(){
myRun1 = new MyRun1(this);
}
public synchronized boolean f(){
System.out.println("MyRun.f()");
while (!myRun1.f()){
}
return true;
}
}
public class MyRun1 extends Thread {
MyRun myRun;
MyRun1(MyRun myRun){
this.myRun = myRun;
}
public synchronized boolean f(){
System.out.println("MyRun1.f()");
while (!myRun.f()){}
return true;
}
}
public static void main(String[] args){
MyRun myRun = new MyRun();
myRun.f();
}
MyRun.f()
MyRun1.f()
MyRun.f()
MyRun1.f()
.
.
.
.
Exception in thread "main" java.lang.StackOverflowError
Main:
public class MyRun extends Thread{
MyRun1 myRun1;
MyRun(){
myRun1 = new MyRun1(this);
}
public synchronized boolean f(){
System.out.println("MyRun.f()");
while (!myRun1.f()){
}
return true;
}
}
public class MyRun1 extends Thread {
MyRun myRun;
MyRun1(MyRun myRun){
this.myRun = myRun;
}
public synchronized boolean f(){
System.out.println("MyRun1.f()");
while (!myRun.f()){}
return true;
}
}
public static void main(String[] args){
MyRun myRun = new MyRun();
myRun.f();
}
MyRun.f()
MyRun1.f()
MyRun.f()
MyRun1.f()
.
.
.
.
Exception in thread "main" java.lang.StackOverflowError
输出:
public class MyRun extends Thread{
MyRun1 myRun1;
MyRun(){
myRun1 = new MyRun1(this);
}
public synchronized boolean f(){
System.out.println("MyRun.f()");
while (!myRun1.f()){
}
return true;
}
}
public class MyRun1 extends Thread {
MyRun myRun;
MyRun1(MyRun myRun){
this.myRun = myRun;
}
public synchronized boolean f(){
System.out.println("MyRun1.f()");
while (!myRun.f()){}
return true;
}
}
public static void main(String[] args){
MyRun myRun = new MyRun();
myRun.f();
}
MyRun.f()
MyRun1.f()
MyRun.f()
MyRun1.f()
.
.
.
.
Exception in thread "main" java.lang.StackOverflowError
所有代码都在主线程上运行,因为您没有启动任何其他线程。因此,方法是否同步并不重要,因为执行是顺序的 您必须调用
myRun.start()
来启动线程。如果希望新线程调用myRun.f()
,则必须重写run()
方法
您还必须启动另一个线程
(类型为MyRun1
)并重写其run
方法
另外,与其扩展线程
类,不如让您的类实现可运行
接口,并将它们的实例传递给线程
构造函数。您的所有代码都在主线程上运行,因为您没有启动任何其他线程。因此,方法是否同步并不重要,因为执行是顺序的
您必须调用myRun.start()
来启动线程。如果希望新线程调用myRun.f()
,则必须重写run()
方法
您还必须启动另一个线程
(类型为MyRun1
)并重写其run
方法
另外,与其扩展线程
类,不如让类实现可运行
接口,并将它们的实例传递给线程
构造函数。Java同步是可重入的
如果一个线程正在执行一个同步块,而该块中的代码直接或间接调用了试图在同一对象上同步的代码,那么它不会执行同步块
将其浓缩:
synchronized (myRun) {
synchronized (myRun1) {
synchronized (myRun) {
System.out.println("Hello");
}
}
}
在这里,将打印Hello
,因为myRun
已在上同步的事实不会再次阻止内部块上的同步。Java同步是可重入的
如果一个线程正在执行一个同步块,而该块中的代码直接或间接调用了试图在同一对象上同步的代码,那么它不会执行同步块
将其浓缩:
synchronized (myRun) {
synchronized (myRun1) {
synchronized (myRun) {
System.out.println("Hello");
}
}
}
在这里,Hello
将被打印出来,因为myRun
已经在上面进行了同步,这一事实不会再次阻止内部块上的同步。看起来您永远不会启动线程,所有这些代码都在同一个线程中运行。myRun.f()在主函数中,拥有一个扩展线程的类是不够的,您必须调用start()
才能有效地拥有一个新线程。似乎您从未启动过线程,所有这些代码都在同一个线程中运行。在主函数中,myRun.f()是不够的。拥有一个扩展线程的类是不够的,您必须调用start()
才能有效地创建一个新线程。但是为什么关键字synchronized没有停止函数f()的入口(第二次)?即使它是一个同步进程?@Aviad,因为只有一个线程调用该方法synchronized
只会锁定其他线程,使其无法同时进入该方法。但是,为什么关键字synchronized不会停止(第二次)进入函数f()?即使它是一个同步进程?@Aviad,因为只有一个线程调用该方法synchronized
只会锁定其他线程,使其无法同时进入该方法。