我试图理解同步,但是当它试图实现它时,我得到一个模糊的结果,同时尝试实现synchronized,看看它。
通过观察输出,很明显两个线程能够同时访问同步块。指导我哪里出错了。
输出:
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-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
答案 0 :(得分:2)
通过观察输出,很明显两个线程能够同时访问同步块。
不,绝对没有证据证明这一点。让我们考虑以下输出:
Display class show method called by- Thread-0
Display class show method called by- Thread-1
下面:
Thread-0
调用show()
,输入synchronized
块,打印出消息,退出show()
(离开synchronized
} block。。Thread-1
调用show()
,输入synchronized
块,打印出消息,退出show()
(离开synchronized
} block。。等等。
如果您希望看到线程相互阻塞,请将synchronized
放在循环周围:
synchronized(d) {
for (int i = 0; i < 10; i++) {
d.show();
}
}
答案 1 :(得分:2)
不同时访问同步块。
您观察到的是:
如果你添加一些跟踪,你会发现在退出之前从未输入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次,那么您应该在synchronized
周围使用for-loop
:
@Override
public void run() {
showSeveralTimes(10);
}
在Display
:
synchronized void showSeveralTimes(int n) {
for(int i = 0 ; i < n ; ++i) {
show();
}
}
答案 2 :(得分:0)
- 首先,对同一对象的两个同步方法的调用不可能进行交错。当一个线程正在为一个对象执行一个synchronized方法时,所有其他线程都会调用同一个对象的同步方法(暂停执行),直到第一个线程完成该对象为止。
- 其次,当同步方法退出时,它会自动与同一对象的同步方法的任何后续调用建立一个先发生关系。这可以保证对所有线程都可以看到对象状态的更改。
所以Thread-n
运行,返回,Thread-n
运行,返回,无限广告(在这种情况下为10)