沈阳男科医院哪家医院好seo软件优化
不能框多:框多了跟单线程没区别
不能框少:
1,框少了可能逻辑上有问题
2,框少了如果运行的快,可能会引发线程安全问题
以经典老题:三窗口卖票的extends方式为例,正常运行结果应该像这样
这是一个框的少的情况,运行
class MyThread extends Thread{
private static int ticket = 100;
private static Object obj = new Object();
public MyThread(String name){super(name);
}public void run() {while (true) {
// if(ticket<10) {
// try {
// sleep(1000);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
// }System.out.println(Thread.currentThread().getName() + "窗口准备卖票");if (ticket == 0) {System.out.println("已售罄");break;}synchronized (obj) {System.out.println(Thread.currentThread().getName()+"售票一张,余票:"+ --ticket);}}}
}public class SynchronizedTest{public static void main(String[] args) {MyThread m1 = new MyThread("窗口1");m1.start();MyThread m2 = new MyThread("窗口2");m2.start();MyThread m3 = new MyThread("窗口3");m3.start();}
}
原因分析:
虽然是同一把锁,但是甲乙丙三个线程运行的速度很快,当ticket=1时,很大概率甲乙丙三者都通过了if的判断,在排队等待卖票,等三个线程卖完,ticket=-2,此后无论怎么判断都不会进入if语句中的break,所以出现了问题
System.out.println(Thread.currentThread().getName() + "窗口准备卖票");if (ticket == 0) {System.out.println("已售罄");break;}synchronized (obj) {System.out.println(Thread.currentThread().getName()+"售票一张,余票:"+ --ticket);}
如果把注释中的sleep语句加上
// if(ticket<10) {
// try {
// sleep(1000);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
// }
运行结果
这就是因为sleep导致在判断之前甲乙丙三个线程就卡在那,不容易遇到两个以上线程同时都通过了if语句判断的情况
然而,再对代码稍加改动,
if(ticket<10) {
改为
if(ticket<11) {
结果又成了这样了
一个框的大小合适的代码长这样
System.out.println(Thread.currentThread().getName() + "窗口准备卖票");synchronized (Object.class) {//反射if (ticket == 0) {System.out.println("已售罄");break;}System.out.println(Thread.currentThread().getName()+"售票一张,余票:"+ --ticket);}
因此结论:
同步代码块既不能太少也不能太多