有时候使用多进程时会导致进程不同步,这样会导致运行结果的错误。
看下面的代码:
class ThreadDemo1 {
public static void main(String[] args) {
TestThread tt = new TestThread();
new Thread(tt).start();
new Thread(tt).start();
new Thread(tt).start();
new Thread(tt).start();
}
}
class TestThread implements Runnable {
int tickets = 100;
public void run() {
while (true) {
if (tickets > 0) {
try {
Thread.sleep(10);
} catch (Exception e) {
}
System.out.println(Thread.currentThread().getName()
+ " is saling ticket " + tickets--);
}
}
}
}
运行结果:
从运行结果可以看出最后输出了负数,因为当一个线程判断了tickets==1时(大于零),这时它睡眠了10毫秒,这时其他进程会没有判断就输出了票数,再将tickets–,这样就会导致输入负数。
要让它不会出错就要用到进程同步块synchronized。
修改代码如下:
class ThreadDemo1 {
public static void main(String[] args) {
TestThread tt = new TestThread();
new Thread(tt).start();
new Thread(tt).start();
new Thread(tt).start();
new Thread(tt).start();
}
}
class TestThread implements Runnable {
int tickets = 100;
String str = new String("");
public void run() {
while (true) {
synchronized (str) {
if (tickets > 0) {
try {
Thread.sleep(10);
} catch (Exception e) {
}
System.out.println(Thread.currentThread().getName()
+ " is saling ticket " + tickets--);
}
}
}
}
}
运行结果:
ynchronized的原理可以这样理解:当程序进入synchronized代码块时会检查对象(这里的对象是str,假设标志位为1运行,为0时阻塞)的标志位,如果为1时将标志位置0之后再运行,当标志位为0时阻塞等标志位为1。但synchronized同步代码块会影响运行速度。
注:String str = new String(“”);语句不能放在run方法里,因为每个线程运行都有自己的run方法,那么就会创建四个str对象,初始标志位都为1.