2.使用同步代码块的方式解决Thread类的线程安全问题
class windows2 extends Thread {
public static int ticket = 100;
public static Object obj = new Object();
@Override
public void run() {
while (true) {
// synchronized(windows2.class){
// windows2.class是一个静态类,只会加载一次 我们要求同步监视器需是对象
//所以从这个角度来说 类也是对象(详情见反射)
synchronized (obj) {
if (ticket > 0) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().
getName() + ":卖票,票号:" + ticket);
ticket--;
} else {
break;
}
}
}
}
}
public class WindowsTest2 {
public static void main(String[] args) {
windows2 w1 = new windows2();
windows2 w2 = new windows2();
windows2 w3 = new windows2();
w1.setName("窗口1");
w2.setName("窗口2");
w3.setName("窗口3");
w1.start();
w2.start();
w3.start();
}
}
**
本题以创建三个窗口卖票,总票数为100为例说明
与实现Runnable接口创建线程的方式不同
-
Thread类的方式创建了 三个子类对象,自然会有三个obj对象,这就造成了同步监视器的不唯一。
-
解决方法为: 将Object对象设置为static
-
备注:关于同步监视器的问题,见本篇第一章