public class TestSynchronized implements Runnable {
/**
* @param args
*/
Timer timer = new Timer();
public static void main(String[] args) {
TestSynchronized testSynchronized=new TestSynchronized();//同一个线程对象开启两个线程
Thread one=new Thread(testSynchronized);
Thread other=new Thread(testSynchronized);
one.setName("one");
other.setName("other");
one.start();
other.start();
}
public void run() {
timer.add(Thread.currentThread().getName()); //不同线程执行同一个对象的方法
}
}
class Timer {
int num = 0;
public void add(String name) {
num++;
try{
Thread.sleep(1000); //线程被打断处,即使没有此方法cpu也可能把时间片让给另外一个线程
System.out.println(name+"you are"+num);
}catch(InterruptedException e){
}
}
}
输出结果:
oneyou are2
otheryou are2
原因:线程one在执行run方法的时候内部调用的是同一timer的add方法,num加1后,时间片让给了其他线程;接着线程two执行timer的add方法,num加1这时线程one恢复继续执行add方法里边的其余语句输出num值这时候num已经是2了。注:这里的sleep方法只是放大了线程间轮流执行的效果。
解决办法:利用对象锁(这里是互斥锁)
public class TestSynchronized implements Runnable {
/**
* @param args
*/
Timer timer = new Timer();
public static void main(String[] args) {
TestSynchronized testSynchronized = new TestSynchronized();// 同一个线程对象开启两个线程
Thread one = new Thread(testSynchronized);
Thread other = new Thread(testSynchronized);
one.setName("one");
other.setName("other");
one.start();
other.start();
}
public void run() {
timer.add(Thread.currentThread().getName()); // 不同线程执行同一个对象的方法
}
}
class Timer {
int num = 0;
public void add(String name) {
synchronized (this) { //某线程执行timer的add方法的时候,就锁住该对象不允许其他线程执行
num++;
try {
Thread.sleep(1000);
System.out.println(name + "you are" + num);
} catch (InterruptedException e) {
}
}
}
}
也可以改写为:
class Timer {
int num = 0;
public synchronized void add(String name) { //执行此方法锁定当前对象
num++;
try {
Thread.sleep(1000);
System.out.println(name + "you are" + num);
} catch (InterruptedException e) {
}
}
}