解决线程安全问题的第二种方法:使用同步方法
使用步骤:
1.把访问了共享数据的代码取出来,放到一个方法中
2.在方法上添加synchronized修饰符
格式:定义方法的格式
修饰符synchronized(锁对象){
可能出现线程安全问题的代码(访问共享数据的代码)
}
public class Demo02Ticket { public static void main(String[] args) { RunnableImpl run=new RunnableImpl(); Thread t1=new Thread(run); Thread t2=new Thread(run); Thread t3=new Thread(run); t1.start(); t2.start(); t3.start(); } }
定义一个同步方法,同步方法也会把方法内部的代码锁住,只让一个线程执行,同步方法的锁对象是谁?就是实现类对象new RunnaImpl()也就是this
public class RunnableImpl implements Runnable { private int ticket=100; Object obj=new Object();//创建锁对象,三个进程用一个锁对象。 @Override public void run() { while (true){ payTicket();} } public synchronized void payTicket(){//定义一个同步方法 if (ticket>0){ //票存在,卖票ticket try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+"-->正在卖"+ticket+"张票"); ticket--; } } }
静态的同步方法:
public class RunnableImpl implements Runnable { private static int ticket=100; Object obj=new Object();//创建锁对象,三个进程用一个锁对象。 @Override public static run() { while (true){ payTicket();} } public static void payTicket(){//定义一个同步方法 synchronized(RunnableImpl.class){ if (ticket>0){ //票存在,卖票ticket try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+"-->正在卖"+ticket+"张票"); ticket--; } } } }