线程同步之同步机制(synchronized)
1.同步代码块。线程操作的共享数据进行同步。synchronized关键字可以用于方法中的某个区块中,表示只对这个区块的资源实行互斥访问。
synchronized(同步锁){
//需要同步操作的代码
}
2.同步方法:当一个方法中的所有代码,全部是线程操作的共享数据的时候,可以将整个方法进行同步。使用synchronized修饰的方法,就叫做同步方法,保证A线程执行该方法的时候,其他线程只能在方法外等着。
public synchronized void method(){
可能会产生线程安全问题的代码
}
/**
* private void pay() 方法中的所有代码
* 都是线程操作的共享数据,不使用同步代码块
* 同步整个方法:方法修饰符上,使用同步关键字
*
* 问题:
* 同步方法中,有对象锁吗,必须有锁
* 锁是对象,当前对象引用 this
*
* 如果方法是静态的,同步中有锁吗
* 静态方法中,同步锁,不是this
*
* 时间差: 静态修饰成员,优先于非静态的成员存在
*
* 程序运行需要编译后的文件class
* class文件也是对象
* 静态方法同步中的对,是class文件这个对象
*
* class文件这个对象只能获取,不能创建
* 固定写法 类名.class (反射)
*
*/
public class Ticket implements Runnable{
//定义票源
private static int tickets = 100;
//private Object object = new Object();
public void run(){
while (true) {
pay();
}
}
//定义方法,实现售票,run()调用
private static void pay(){
synchronized (Ticket.class) {
if (tickets > 0) {
//线程先别执行,休息一会
try {
Thread.sleep(10);
} catch (Exception ex) {
}
System.out.println(Thread.currentThread().getName() + "出售第::" + tickets--);
}
}
}
}
/**
* 优化:
* 线程售票动作,抽取到一个方法中
* run()调用
*/
public class ThreadDemo {
public static void main(String[] args) {
//创建Runnable接口实现类对
Ticket ticket = new Ticket();
//创建线程对象,3个
Thread t0 = new Thread(ticket);
Thread t1 = new Thread(ticket);
Thread t2 = new Thread(ticket);
t0.start();
t1.start();
t2.start();
}
}