解决线程安全问题的方法
解决线程安全问题的方法一sychronized
package Text2; public class RunnableImpl1 implements Runnable{ //定义一个多线程共享的票源 private int ticket=100; //创建一个锁对象 Object obj=new Object(); //设置线程任务:卖票 @Override public void run() { //使用死循环,让卖票操作重复执行 while(true){ //同步代码块 synchronized (obj){ //先判断票是否存在 if(ticket>0){ //提高安全问题出现的概率,让程序睡眠 try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } //票存在,卖票 System.out.println(Thread.currentThread().getName()+"-->正在卖第"+ticket); ticket--; } } } } }
package Text2; //模拟买票案例,创建3个线程,同时开启,对共享的票进行出售 public class demo5Ticket { public static void main(String[] args) { //创建Runnable接口的实现类对象 RunnableImpl1 run=new RunnableImpl1(); //创建Thread类对象,构造方法中传递Runnable接口的实现类对象 Thread t1=new Thread(run); Thread t2=new Thread(run); Thread t3=new Thread(run); //调用start方法开启多线程 t1.start(); t2.start(); t3.start(); } }
解决线程安全问题的方法二同步方法
package Text2; public class RunnableImpl1 implements Runnable{ //定义一个多线程共享的票源 private int ticket=100; //创建一个锁对象 Object obj=new Object(); //设置线程任务:卖票 @Override public void run() { //使用死循环,让卖票操作重复执行 while(true){ payTicket(); } } public synchronized void payTicket(){ //先判断票是否存在 if(ticket>0){ //提高安全问题出现的概率,让程序睡眠 try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } //票存在,卖票 System.out.println(Thread.currentThread().getName()+"-->正在卖第"+ticket); ticket--; } } }
解决线程安全问题的方法三Lock锁
package Text2; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class RunnableImpl1 implements Runnable{ //定义一个多线程共享的票源 private int ticket=100; //创建一个锁对象 Object obj=new Object(); Lock l=new ReentrantLock(); //设置线程任务:卖票 @Override public void run() { //使用死循环,让卖票操作重复执行 while(true){ //在可能会出现安全问题的代码前调用Lock接口中的lock方法获取锁 l.lock(); //先判断票是否存在 if(ticket>0){ //提高安全问题出现的概率,让程序睡眠 try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } //票存在,卖票 System.out.println(Thread.currentThread().getName()+"-->正在卖第"+ticket); ticket--; } //在可能会出现安全问题的代码后调用Lock接口中的unlock方法释放锁 l.unlock(); } } }
用finally可提高程序效率