【发布时间】:2018-01-03 07:55:16
【问题描述】:
我正在通过Thread 的行为测试我的技能。当我实现Runnable 接口和synchronized 运行方法时,我得到了绝对的结果。但是,当我扩展 Thread 类时,结果是不可预测的。以下是两种情况。我认为,两种情况下的线程都使用相同的资源。
案例 1 Runnable
class Counter{
int count;
public void doCount(){
count=count+1;
}
public int getCount(){
return count;
}
}
public class One implements Runnable{
Counter counter = new Counter(); // common object to be shared with two threads
public void run(){
synchronized (this) {
for(int i=0;i<10000;i++){
counter.doCount();
}
}
}
public static void main(String[] args) throws InterruptedException {
One one = new One();
Thread t1 = new Thread(one);// using same resource 'one'
Thread t2 = new Thread(one);// using same resource 'one'
t1.start();
t2.start();
Thread.sleep(2000); // to give both threads time to complete
System.out.println(one.counter.getCount());
}
}
案例 2 Thread
class Counter{
int count;
public void doCount(){
count=count+1;
}
public int getCount(){
return count;
}
}
public class One extends Thread{
Counter counter; //common object to be shared with two threads
One(Counter counter){
this.counter = counter;
}
public void run(){
synchronized (this) {
for(int i=0;i<10000;i++){
counter.doCount();
}
}
}
public static void main(String[] args) throws InterruptedException {
Counter counter = new Counter();
One o1 = new One(counter);// using same resource counter
One o2 = new One(counter);// using same resource counter
o1.start();
o2.start();
Thread.sleep(2000); // to give both threads time to complete
System.out.println(counter.getCount());
}
}
对于案例 1,我每次都得到 20000 的输出。但对于案例 2,我每次都得到随机值。为什么会这样?案例 2 也在两个线程之间使用相同的资源,那么他们为什么停止获取synchronized。谁能解释一下。。我要疯了!!
【问题讨论】:
-
问问自己:第一种情况下
synchronized(this)中的this是什么,第二种情况下是什么。 -
好的等等,问..我的意思是想..
-
因为 .. 你不是在柜台上同步,而是在其他有多个实例的东西上同步?
-
你说得对。
this是 One 的实例。在第一种情况和第二种情况下,您创建了多少个One实例? -
不。那不是问题。确实有两个 One 实例,但都共享同一个计数器。问题是第一个线程在 One 的第一个实例上同步,第二个线程在 One 的第二个实例上同步。所以他们访问一个共享资源(计数器),但在不同的锁上同步。所以在第一个线程中进入同步块并不会阻止另一个线程进入它的同步块。
标签: java multithreading synchronization