照着《Java开发技术大全》上抄了一段java线程互斥的代码,不是很明白,请高手帮忙看看。
public class SynchronizedThread extends Thread {
private static int count = 0;
private static boolean flag = true; public synchronized void run() {
int i = 0;
for (; i < 100; i++) {
if (!flag) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
flag = false;
count = count + 1;
System.out.println("I am " + getName() + ".My count is:"
+ count);
flag = true;
notifyAll();
try {
sleep(10);//当前运行的进程sleep,可能notify后进入睡眠状态
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} public SynchronizedThread(String name) {
super(name);
}
}
public class SynchronizerTest {
public static void main(String[] args) {
SynchronizedThread a ,b,c;
a= new SynchronizedThread("A");
c=new SynchronizedThread("C");
b=new SynchronizedThread("B");
b.start();
a.start();
c.start();
}
}
这两段程序很简单,但是我有三点疑惑的地方。
1,为什么最后输出的count值会大于100?同样地,为什么最后的值不是300?
2,为什么最先开始的线程抢占了大部分的运行时间,而A和C出现的很少。
3,将System.out.println那句放到notifyAll之后,为什么三个线程运行的时间较均匀?同时,为什么不能完全防止乱序和count值重复输出。希望高手予以赐教。
public class SynchronizedThread extends Thread {
private static int count = 0;
private static boolean flag = true; public synchronized void run() {
int i = 0;
for (; i < 100; i++) {
if (!flag) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
flag = false;
count = count + 1;
System.out.println("I am " + getName() + ".My count is:"
+ count);
flag = true;
notifyAll();
try {
sleep(10);//当前运行的进程sleep,可能notify后进入睡眠状态
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} public SynchronizedThread(String name) {
super(name);
}
}
public class SynchronizerTest {
public static void main(String[] args) {
SynchronizedThread a ,b,c;
a= new SynchronizedThread("A");
c=new SynchronizedThread("C");
b=new SynchronizedThread("B");
b.start();
a.start();
c.start();
}
}
这两段程序很简单,但是我有三点疑惑的地方。
1,为什么最后输出的count值会大于100?同样地,为什么最后的值不是300?
2,为什么最先开始的线程抢占了大部分的运行时间,而A和C出现的很少。
3,将System.out.println那句放到notifyAll之后,为什么三个线程运行的时间较均匀?同时,为什么不能完全防止乱序和count值重复输出。希望高手予以赐教。
线程运行多久是由CPU控制的。
你看你的代码,首先你要搞清楚,synchronized关键字修饰方法的时候,它的同步监视器对象是什么?
应该是this,对吧! 但是你每个对象都有不同的this,就是每一个this调用自己的方法,例如这里你的a对象和b对象根本就没有任何影响