Java 关于使用同步方法的几个问题

Java 关于使用同步方法的几个问题,java,synchronization,Java,Synchronization,我试图理解同步,但当它试图实现它时,我得到了一个不明确的结果,当尝试实现同步时,请看一看 通过观察输出,很明显两个线程能够同时访问同步块。指引我哪里出了问题 输出: Display class show method called by- Thread-0 Display class show method called by- Thread-0 Display class show method called by- Thread-0 Display class show method cal

我试图理解同步,但当它试图实现它时,我得到了一个不明确的结果,当尝试实现同步时,请看一看

通过观察输出,很明显两个线程能够同时访问同步块。指引我哪里出了问题

输出:

Display class show method called by- Thread-0
Display class show method called by- Thread-0
Display class show method called by- Thread-0
Display class show method called by- Thread-0
Display class show method called by- Thread-0
Display class show method called by- Thread-0
Display class show method called by- Thread-0
Display class show method called by- Thread-1
Display class show method called by- Thread-1
Display class show method called by- Thread-1
Display class show method called by- Thread-1
Display class show method called by- Thread-1
Display class show method called by- Thread-1
Display class show method called by- Thread-1
Display class show method called by- Thread-1
Display class show method called by- Thread-1
Display class show method called by- Thread-1
Display class show method called by- Thread-0
Display class show method called by- Thread-0
Display class show method called by- Thread-0
节目:

package com.StackOverFlow.Doubts3;

public class Dbts5 {
public static void main(String[] args) {

    Display d1= new Display();
    MyThreads th1= new MyThreads(d1, "Thread1");

    th1.start();

    MyThreads th2= new MyThreads(d1, "Thread2");

    th2.start();




}
}

class MyThreads extends Thread{


Display d;
String name;


@Override
public void run() {
    super.run();
    for (int i = 0; i < 10; i++) {
        d.show();   
    }



}

public MyThreads() {}

MyThreads(Display d, String name){
    this.d=d;
    this.name=name;
}


}

class Display{

synchronized void show(){
    System.out.println("Display class show method called by- "+Thread.currentThread().getName());
    try {
        Thread.currentThread().sleep(300);
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

}
}
通过观察输出,很明显两个线程能够同时访问同步块

没有,绝对没有证据。让我们考虑下面的输出:

Display class show method called by- Thread-0
Display class show method called by- Thread-1
在这里:

Thread-0调用show,进入同步块,打印消息,退出show,离开同步块。 Thread-1调用show,进入同步块,打印消息,退出show,离开同步块。 等等

如果希望看到线程彼此阻塞,请在循环中放置synchronized:

synchronized(d) {
    for (int i = 0; i < 10; i++) {
        d.show();   
    }
}
通过观察输出,很明显两个线程能够同时访问同步块

没有,绝对没有证据。让我们考虑下面的输出:

Display class show method called by- Thread-0
Display class show method called by- Thread-1
在这里:

Thread-0调用show,进入同步块,打印消息,退出show,离开同步块。 Thread-1调用show,进入同步块,打印消息,退出show,离开同步块。 等等

如果希望看到线程彼此阻塞,请在循环中放置synchronized:

synchronized(d) {
    for (int i = 0; i < 10; i++) {
        d.show();   
    }
}

您的同步块不能同时访问

你观察到的是:

线程0进出7次 线程1进出10次 线程0进出3次 如果您添加了一些跟踪,您会更好地看到,在退出之前,show不会被输入两次:

synchronized void show(){
    System.out.println(Thread.currentThread().getName() + " In");
    // do show
    System.out.println(Thread.currentThread().getName() + " Out");
}
你会看到:

Thread-0 In
Display class show method called by- Thread-0
Thread-0 Out
// ...
Thread-1 In
Display class show method called by- Thread-1
Thread-1 Out
// ...
Thread-0 In
Display class show method called by- Thread-0
Thread-0 Out
如果希望线程在释放锁之前调用show n次,则应在for循环中使用synchronized:

并在显示器上显示:


您的同步块不能同时访问

你观察到的是:

线程0进出7次 线程1进出10次 线程0进出3次 如果您添加了一些跟踪,您会更好地看到,在退出之前,show不会被输入两次:

synchronized void show(){
    System.out.println(Thread.currentThread().getName() + " In");
    // do show
    System.out.println(Thread.currentThread().getName() + " Out");
}
你会看到:

Thread-0 In
Display class show method called by- Thread-0
Thread-0 Out
// ...
Thread-1 In
Display class show method called by- Thread-1
Thread-1 Out
// ...
Thread-0 In
Display class show method called by- Thread-0
Thread-0 Out
如果希望线程在释放锁之前调用show n次,则应在for循环中使用synchronized:

并在显示器上显示:

引述:

首先,同一对象上的两个同步方法调用不可能交错。当一个线程正在为一个对象执行同步方法时,为同一对象块调用同步方法的所有其他线程将暂停执行,直到第一个线程处理完该对象为止。 其次,当同步方法退出时,它会自动与同一对象的同步方法的任何后续调用建立“发生在之前”关系。这保证了对象状态的更改对所有线程都可见。 所以Thread-n运行,返回,Thread-n运行,返回,无限或10在本例中

引用一个:

首先,同一对象上的两个同步方法调用不可能交错。当一个线程正在为一个对象执行同步方法时,为同一对象块调用同步方法的所有其他线程将暂停执行,直到第一个线程处理完该对象为止。 其次,当同步方法退出时,它会自动与同一对象的同步方法的任何后续调用建立“发生在之前”关系。这保证了对象状态的更改对所有线程都可见。
因此,Thread-n运行,返回,Thread-n运行,返回,无限或10在本例中

我看不出输出如何显示线程同时访问同步块。事实上,由于您在show方法中只输出一行,所以除了它已被执行之外,无法确定show中发生了什么。您认为他们为什么同时访问它?一个线程打印出消息,退出函数,然后另一个线程进入…为什么要向下投票?OP问我哪里出了问题。当你不明白发生了什么时,问一个问题是完全合法的。同步的效果如下:两个线程不能同时执行同步区域。您的输出显示t0、t1、t0再次按顺序执行同步区域。它没有显示t1和t0同时在同步区域中。@user2900314循环未同步,只有此show方法是同步的,因此一旦一个线程退出它,另一个线程可能会进入,即使第一个线程未使用循环。我看不出输出如何显示线程同时访问同步块。在里面
事实上,由于您在show方法中只输出一行,所以除了它已被执行之外,无法确定show中发生了什么。您认为他们为什么同时访问它?一个线程打印出消息,退出函数,然后另一个线程进入…为什么要向下投票?OP问我哪里出了问题。当你不明白发生了什么时,问一个问题是完全合法的。同步的效果如下:两个线程不能同时执行同步区域。您的输出显示t0、t1、t0再次按顺序执行同步区域。它不显示t1和t0同时处于同步区域。@user2900314循环未同步,只有此show方法是同步的,因此,一旦一个线程退出,另一个线程可能会进入,即使第一个线程未使用循环。我在MyThread的run方法中使用for循环,所以我希望只有一个人可以使用同步块。为什么这是错误的。我可能听起来很傻,但我想知道为什么我会出错。我在MyThread的run方法中使用for循环,所以我希望只有一个可以使用synchronized块。为什么这是错误的。我可能听起来很傻,但我想知道为什么我会出错。