java 多线程详解二 买票示例
2016-08-30 21:53
531 查看
问题描述:写一个卖票程序,假设有10张票(实际可能有几百万张),有3个窗口同时售票,打印显示卖出的每张票。
(1)实现方式一(错误示例):
发现结果符合题意,依次打印出车票。结果正确。下面我们修改程序,每卖出一张票休眠200毫秒(根据电脑配置不同休眠时间自己调整)。
安全问题:我们发现当睡眠200毫秒后程序出现了问题,我们多卖出了8,-1,-2 三张票。出现了安全问题。
原因:两个或以上数量的线程同时执行了相同的代码,同时卖出一样的票。导致同样的票买了两次或多次。
2.实现方式二(安全问题解决方案)
解决方案:同步锁
现在我们的程序就可以成功运行了。
总结:
1.多线程存在线程安全问题。
2.可以用同步锁的方式解决同步问题。
3.线程安全问题产生的原因:
1,多个线程在操作共享的数据。
2,操作共享数据的线程代码有多条。
解决思路;
就是将多条操作共享数据的线程代码封装起来,当有线程在执行这些代码的时候,
其他线程时不可以参与运算的。
必须要当前线程把这些代码都执行完毕后,其他线程才可以参与运算。
在java中,用同步代码块就可以解决这个问题。
同步代码块的格式:
synchronized(对象)
{
需要被同步的代码 ;
}
4.同步的好处和弊端
同步的好处:解决了线程的安全问题。
同步的弊端:相对降低了效率,因为同步外的线程的都会判断同步锁。
5.同步的前提:
同步中必须有多个线程并使用同一个锁。
(1)实现方式一(错误示例):
public class Ticket implements Runnable { int num = 10; @Override public void run() { while (num>0) { num--; System.out.println(Thread.currentThread().getName() + ":" + num); } } }
public class TicketDemo { public static void main(String[] args) { Ticket ticket=new Ticket(); Thread thread1=new Thread(ticket); Thread thread2=new Thread(ticket); Thread thread3=new Thread(ticket); thread1.start(); thread2.start(); thread3.start(); } }
Thread-0:9 Thread-0:8 Thread-0:7 Thread-0:6 Thread-0:5 Thread-0:4 Thread-0:3 Thread-0:2 Thread-0:1 Thread-0:0 Process finished with exit code 0
发现结果符合题意,依次打印出车票。结果正确。下面我们修改程序,每卖出一张票休眠200毫秒(根据电脑配置不同休眠时间自己调整)。
public class Ticket implements Runnable { int num = 10; @Override public void run() { while (true) { try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); } if(num>0){ num--; System.out.println(Thread.currentThread().getName() + ":" + num); } } } }
Thread-0:9 Thread-1:8 Thread-2:8 Thread-0:7 Thread-1:6 Thread-2:5 Thread-0:4 Thread-1:3 Thread-2:2 Thread-0:1 Thread-2:0 Thread-1:-1 Thread-0:-2 Process finished with exit code 0
安全问题:我们发现当睡眠200毫秒后程序出现了问题,我们多卖出了8,-1,-2 三张票。出现了安全问题。
原因:两个或以上数量的线程同时执行了相同的代码,同时卖出一样的票。导致同样的票买了两次或多次。
2.实现方式二(安全问题解决方案)
解决方案:同步锁
public class Ticket implements Runnable { int num = 10; Object object=new Object(); @Override public void run() { while (true) { try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (object){ if (num>0) { num--; System.out.println(Thread.currentThread().getName() + ":" + num); } } } } }
现在我们的程序就可以成功运行了。
总结:
1.多线程存在线程安全问题。
2.可以用同步锁的方式解决同步问题。
3.线程安全问题产生的原因:
1,多个线程在操作共享的数据。
2,操作共享数据的线程代码有多条。
解决思路;
就是将多条操作共享数据的线程代码封装起来,当有线程在执行这些代码的时候,
其他线程时不可以参与运算的。
必须要当前线程把这些代码都执行完毕后,其他线程才可以参与运算。
在java中,用同步代码块就可以解决这个问题。
同步代码块的格式:
synchronized(对象)
{
需要被同步的代码 ;
}
4.同步的好处和弊端
同步的好处:解决了线程的安全问题。
同步的弊端:相对降低了效率,因为同步外的线程的都会判断同步锁。
5.同步的前提:
同步中必须有多个线程并使用同一个锁。
相关文章推荐
- java 多线程-锁详解及示例代码
- java多线程小示例详解
- Windows Forms 实现安全的多线程详解(附带程序代码示例)
- Windows Forms 实现安全的多线程详解(附带程序代码示例) (摘自网络)
- java多线程学习-java.util.concurrent详解(一) Latch/Barrier
- JAVA 注解示例 详解
- java常用类解析九:Applet(JApplet)详解及示例
- [原创] Windows Forms 实现安全的多线程详解(附带程序代码示例)
- java多线程总结四:volatile、synchronized示例
- 多线程买票拉-java
- JAVA多线程详解
- java多线程总结四:volatile、synchronized示例
- java多线程示例
- JAVA多线程编程:wait() 和 notify() 方法示例
- 用JAVA中的多线程示例银行取款问题
- 用JAVA中的多线程示例生产者和消费者问题
- Java中的Drag and Drop详解与代码示例
- 菜鸟课堂:详解Java多线程开发中的数据同步
- Java中的Drag and Drop详解与代码示例
- java多线程学习-java.util.concurrent详解(三)ScheduledThreadPoolExecutor