同步方法,静态同步方法
同步方法:
卖票案例出现了线程安全问题
卖出了不存在的票和重复的票
解决线程安全问题的二种方案:使用同步方法
使用步骤:
1.把访问了共享数据的代码抽取出来,放到一个方法中
2.在方法上添加synchronized修饰符
格式:定义方法的格式
修饰符 synchronized 返回值类型 方法名(参数列表){
可能会出现线程安全问题的代码(访陶了共享数据的代码)
}
class window3 implements Runnable{ private int ticket = 100; @Override public void run() { while (true){ show(); } } public synchronized void show(){//同步监视器:this(未显示声明而已) if (ticket > 0) { try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "卖票,票号为:" + ticket); ticket--; } } } public class WindowTest3 { public static void main(String[] args) { window3 w = new window3(); Thread t1 = new Thread(w); Thread t2 = new Thread(w); Thread t3 = new Thread(w); t1.setName("线程1"); t2.setName("线程2"); t3.setName("线程3"); t1.start(); t2.start(); t3.start(); } }
静态同步方法:
静态的同步方法
锁对象是谁?
不能是this
this是创建对象之后产生的,静态方法优先于对象
静态方法的锁对象是本类的cLass属性-->class文件对象(反射)
public class RunnableImp implements Runnable { //定义一个多线程共享的票源 private static int ticket=100; //创建一个锁对象 Object obj=new Object(); //定义线程任务:买票 @Override public void run() { //使用死循环让卖票重复执行 while(true){ payTicketStatic(); } } /* 定义一个静态同步方法: 同步方法也会把方法内部的代码锁住,只让一个方法执行 锁对象不是this this是创建对象之后产生的,静态方法优于对象,静态方法的锁对象是本类的class属性--class文件对象 */ public static /*synchronized*/ void payTicketStatic(){ //判断票是否存在 synchronized(RunnableImp.class){ if(ticket>0){ //为了提高安全问题出现的次数。让程序睡眠一下 try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+"---正在卖票"+ticket+"张票"); ticket--; } } } }