SellTickets.java
package cn.itcast.synchronize;
public class SellTickets implements Runnable{
private int tickets = 100;
//定义同一把锁
private Object obj = new Object();
@Override
public void run() {
while(true){
// t1,t2,t3都能走到这里
// 假设t1抢到CPU的执行权,t1就要进来
// 假设t2抢到CPU的执行权,t2就要进来,发现门是关着的,进不去。所以就等着。
// 门(开、关)
synchronized(obj){ // 发现这里的代码将来是会被锁上的,所以t1进来后,就锁了。(关)
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
if(tickets>0){
System.out.println(Thread.currentThread().getName()+"正在出售第:"+(tickets--)+"张票");
}
} // t1出来后,然后就开门。 t1,t2,t3继续抢占CPU的执行权
}
}
}
SellTicketsTest.java
package cn.itcast.synchronize;
public class SellTicketsTest {
public static void main(String[] args) {
SellTickets st = new SellTickets();
Thread st1 = new Thread(st);
Thread st2 = new Thread(st);
Thread st3 = new Thread(st);
st1.setName("窗口1");
st2.setName("窗口2");
st3.setName("窗口3");
st1.start();
st2.start();
st3.start();
}
}
总结:
同步的特点:
前提:
多个线程
注意事项:
多个线程使用的是同一把锁对象
同步的好处:
解决多线程的安全问题
同步的弊端:
当线程相当多时,因为每个线程都会去判断同步上的锁,
这是很耗费资源的,无形中会降低程序的运行效率
同步方法的锁对象是 this
静态同步方法的锁对象是 类的字节码文件对象 类名.class
线程安全的类:
StringBuffer、Vector、Hashtable
Vector是线程安全的时候才考虑使用的,但是我还说过,即使要安全,我们
也不使用,那么到底用谁吶?
List<String> list = Collections.synchronizedList(new ArrayList<String>())