基本理解
synchronized锁是Java内置的锁
特性:
- 互斥锁:当一个线程获得了锁后其他线程就不能再获得锁
- 可重入锁:同一线程可以重复的获得锁
使用方式:同步方法,同步代码块
例子
public class GetTickets {
//此处应该理解这里的对象tickets仅仅是一份重写了run方法的对象资源
//当new Thread对象去start()它时,此时才建立了线程,只要使用的参数
//是这个对象多个Thread对象之间实际上是共享一份资源的
//因此在两个线程中对sale()方法调用时会产生线程冲突
//同样的如果将synchronized修饰加到run()方法上,那么在任一线程
//调用run()方法时都会对该方法加锁并产生互斥阻塞,run()方法也仅
//仅是该对象资源的一部分,并不因为它是重写的run()方法而有区别。
public static void main(String[] args) {
Tickets tickets=new Tickets();
Thread t1=new Thread(t,"窗口1");
Thread t2=new Thread(t,"窗口2");
t1.start();
t2.start();
}
}
class Tickets implements Runnable{
private int count=100;
@Override
public void run() {
while(count>0) {
try {
//run()方法并没有锁,所以可以有多个线程进入到这个位置
//在这里进行堵塞来产生多个线程同一位置等待的效果
//如果不堵塞的话,由于这里线程体执行很快,可能在不会产生冲突
Thread.sleep(50);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//阻塞结束点
sale();
}
}
private synchronized void sale() {
//在这里进行判断是因为线程的阻塞结束进入sale()方法是在while
//判断之后,当有多个线程进入等待点时,当第一个符合规则的线程
//完成了票数的修改,其他已经经过while判断的线程,依然可以进入
//sale()方法,此时的修改就不符合规则了。
if(count>0) {
count--;
System.out.println(Thread.currentThread().getName()+"卖出"+(100-count)+"张票");
}
}
}