java学习多线程之卖票示例
这一节我们来说一个示例就是卖票示例:
需求:
我们现在有100张票,然后分四个窗口来卖,直到卖完为止。
思路:
1、先定一个一个票类,描述票的属性,还有打印卖出的票,并且实现Runnable中的run方法。
2、定义一个主方法,把这个类当成一个独立的运行程序。
3、在主方法当中创建4个线程来卖票。
代码:
class Ticket implements Runnable
{ int num = ; public void sellT()
{ while(true)
{ if(num>)
System.out.println(num--); } } public void run()
{ sellT(); } } class ThreadTickets
{ public static void main(String[] args) { Ticket p = new Ticket(); Thread t1 = new Thread(p);
Thread t2 = new Thread(p);
Thread t3 = new Thread(p); t1.start();
t2.start();
t3.start(); } }
我们写完之后,在不是很慢的电脑上运行都是正常的,但是我们的这个程序总体上安全么?如果在if(num>0)这个地方线程一刚要执行的时候被切换出去了那么num此时如果恰巧是1的话,那么此时线程二进来后1>0之后就直接打印1,但是在线程一苏醒之后,这时候他不再判断num是否大于零而是直接打印了 num--这个时候就出现了0甚至是负数。这就是多线程当中出现的问题,那么如何解决这个问题。我们可以试想一下,如果在线程一退出的时候,能够让num不让其他对象访问,直到线程一苏醒之后处理完num之后,再让出num的控制权的话,这样是不是很安全呢,这个也叫做多线程当中的同步。同步是指,在同时有多个线程运行的时候,其中有一段代码块一个时候只能允许一个线程来处理,只有这个线程处理完了之后,其他的线程才有机会重新掌管这个代码块,周而复始。
java为了能够让我们处理上述的不同步问题就是一个线程执行的同时,其中共享的资源分别被其他的线程来执行着,这样就可能造成输出了不该输出的语句。为我们提供了一个关键字叫做synchronized。这个关键词的使用方法,是指定一个锁,来访问其内部的代码块。如果一个线程要处理访问其中的代码块的话,必须先拿到锁。并且这个锁要是所有的线程公用的锁才好,这样才能够起到锁的作用。当一个线程拿到锁之后,其他线程来访问的话如果没有锁,则一直判断另一个线程的锁是否释放,只有持有锁的线程把任务执行完之后,才会释放锁。这个锁一释放之后,其他的线程就有机会持有这个锁,然后进行任务的操作。这样就在多线程的情况下,保证了在某一个时刻,只能由一个线程来执行这段同步代码块。也保证了共享数据的安全性,不至于这段数据在被修改之后,其他线程仍然认为这个数据就是之前的按个数据的问题。究竟如何使用呢,代码如下:
class Ticket implements Runnable
{ int num = ; Object obj = new Object(); public void sellT()
{ while(true)
{
synchronized (obj)
{ if(num>)
{
try
{ Thread.sleep(); }catch(InterruptedException e)
{ }
System.out.println("The CurrentThread is:"+Thread.currentThread().getName()+"The num is:"+num--); } }
} } public void run()
{ sellT(); } } class ThreadTickets
{ public static void main(String[] args) { Ticket p = new Ticket(); Thread t1 = new Thread(p);
Thread t2 = new Thread(p);
Thread t3 = new Thread(p); t1.start();
t2.start();
t3.start(); } }
其中同步代码块还有一种简写的形式,也就是说把代码块关键字synchronized( lock ){},把synchronized直接放到函数上,这样整个函数就是同步的了。也就是:
class Ticket implements Runnable
{ int num = ; Object obj = new Object(); public void sellT()
{ while(true)
{
try
{ Thread.sleep(); }catch(InterruptedException e)
{ }
pTicket(); } } public synchronized void pTicket()
{ if(num>)
{ System.out.println("The CurrentThread is:"+Thread.currentThread().getName()+"The num is:"+num--); } } public void run()
{ sellT(); } } class ThreadTickets
{ public static void main(String[] args) { Ticket p = new Ticket(); Thread t1 = new Thread(p);
Thread t2 = new Thread(p);
Thread t3 = new Thread(p); t1.start();
t2.start();
t3.start(); } }
synchronized这个关键字加到代码块之前就是同步代码块,加到函数上面就是同步函数。
java学习多线程之卖票示例的更多相关文章
- Java之多线程窗口卖票问题(Runnable)
/** * 例子:创建三个窗口卖票,总票数为100张.使用实现Runnable接口的方式 * 存在线程的安全问题,待解决. */class Window1 implements Runnable{ p ...
- Java之多线程窗口卖票问题(Thread)
/** * * 例子:创建三个窗口卖票,总票数为100张.使用继承Thread类的方式 * * 存在线程的安全问题,待解决. * */class Window extends Thread{ priv ...
- java多线程实现卖票小程序
package shb.java.demo; /** * 多线程测试卖票小程序. * @Package:shb.java.demo * @Description: * @author shaobn * ...
- java 多线程之卖票两种方式
1.通过extends Thread /* 需求:简单的卖票,多个窗口同时买票 (共用资源) 创建线程的第二种方式:实现Runnable接口 步骤: 1,定义类实现Runnable接口 2,覆盖/重写 ...
- Java学习多线程第二天
内容介绍 线程安全 线程同步 死锁 Lock锁 等待唤醒机制 1 多线程 1.1 线程安全 如果有多个线程在同时运行,而这些线程可能会同时运行这段代码.程序每次运行结果和单线程运行的结果 ...
- java学习——多线程
本文内容来源于 历经5年锤练--史上最适合初学者入门的Java基础视频 线程:就是进程中一个负责程序执行的控制单元(执行路径) 每一个线程都有自己运行的内容.这个内容可以称为线程要执行的任务. 多线 ...
- Java学习---多线程的学习
基础知识 每个正在系统上运行的程序都是一个进程(process).每个进程包含一到多个线程(thread).进程也可能是整个程序或者是部分程序的动态执行. 线程是一组指令的集合,或者是程序的特殊段,它 ...
- Java学习多线程第一天
内容介绍 Thread 线程创建 线程池 线程状态图 1 多线程 1.1 多线程介绍 学习多线程之前,我们先要了解几个关于多线程有关的概念. 进程:进程指正在运行的程序.确切的来说,当一个程序 ...
- java学习多线程之创建多线程一
现在我们有这么一个需求,就是在主线程在运行的同时,我们想做其他的任务,这个时候我们就用到了多线程.那么如何创建多线程,我们知道在系统当中qq的多线程创建是由操作系统来完成的,那么如果我们想在java当 ...
随机推荐
- 谨以此错误警醒自己---java.lang.ClassNotFoundException:
今天在做一个小型的实例,用了面向接口编程,采用了工厂来获取数据源和实例,在从配置文件读取实例时,报了个错误如下图: 于是一个一个的类去找错误,最后也没找到,以为工厂代码出错了,看了好几次也没看出来错误 ...
- /etc/shadow
这样,用户帐户本身在 /etc/passwd 中定义.Linux 系统包含一个 /etc/passwd 的同伴文件,叫做 /etc/shadow.该文件不像 /etc/passwd,只有对于 root ...
- swift入门-day01
Swift 简介 简介 Swift 语言由苹果公司在 2014 年推出,用来撰写 OS X 和 iOS 应用程序 2014 年,在 Apple WWDC 发布 历史 2010 年 7 月,苹果开发者工 ...
- UIImagePickerController显示中文界面
iOS开发中,我们经常遇到获取拍照.相册中图片的功能,就必然少不了UIImagePickerController,但是我们发现当我们使用它的时候,它的页面是英文的,看着很别扭,国人还是比较喜欢看中文界 ...
- apache .htaccess 伪静态重定向,防盗链 限制下载...
301全站跳转 RewriteEngine OnRewriteCond %{HTTP_HOST} ^www\.old\.net$ [NC]RewriteRule ^(.*)$ http://www.n ...
- php代码锁
在为台湾公司开发“保证金交易系统”的过程中,出现了这样的情况: 一个间银行有n个操作员,可以同时在系统中下单,系统需要判断银行的保证金是否足够来决定是否可以下单成功.账号保证金足够,正常下单,账号保证 ...
- c++11的for新用法 (重新练习一下for_each)
看到手册的代码里面有个for的很奇怪的用法,用了一把 http://www.cplusplus.com/reference/unordered_set/unordered_set/insert/ ...
- Objective-C中的runtime的原理和用法
一.runtime介绍 runtime翻译就是运行时,我们称为运行时机制.在OC中最重要的体现就是消息发送机制. 1)在C语言中,程序在编译过程中就决定调用哪个函数. 2)在OC中,编译的时候不会决定 ...
- VMware网络选项分析
摘自资料:VMware网卡选项分析.zip 很多朋友都曾问到关于Guest和Host互联,其实这并不是一件困难的事情,只要能够理解VMware的网络模型即可,今天结合着我的虚拟机,来详细介绍一下VMw ...
- Axure草记
页面控件和DataSet绑定,DataSet和输入控件绑定(通过临时变量) 双击Repeater进入之后,你会发现下面已经默认添加了3行,这代表着,每增加一行将会重复3遍: Repeater可以只是部 ...