这一节我们来说一个示例就是卖票示例:

需求:

我们现在有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学习多线程之卖票示例的更多相关文章

  1. Java之多线程窗口卖票问题(Runnable)

    /** * 例子:创建三个窗口卖票,总票数为100张.使用实现Runnable接口的方式 * 存在线程的安全问题,待解决. */class Window1 implements Runnable{ p ...

  2. Java之多线程窗口卖票问题(Thread)

    /** * * 例子:创建三个窗口卖票,总票数为100张.使用继承Thread类的方式 * * 存在线程的安全问题,待解决. * */class Window extends Thread{ priv ...

  3. java多线程实现卖票小程序

    package shb.java.demo; /** * 多线程测试卖票小程序. * @Package:shb.java.demo * @Description: * @author shaobn * ...

  4. java 多线程之卖票两种方式

    1.通过extends Thread /* 需求:简单的卖票,多个窗口同时买票 (共用资源) 创建线程的第二种方式:实现Runnable接口 步骤: 1,定义类实现Runnable接口 2,覆盖/重写 ...

  5. Java学习多线程第二天

    内容介绍 线程安全 线程同步 死锁 Lock锁 等待唤醒机制 1    多线程 1.1     线程安全 如果有多个线程在同时运行,而这些线程可能会同时运行这段代码.程序每次运行结果和单线程运行的结果 ...

  6. java学习——多线程

    本文内容来源于  历经5年锤练--史上最适合初学者入门的Java基础视频 线程:就是进程中一个负责程序执行的控制单元(执行路径) 每一个线程都有自己运行的内容.这个内容可以称为线程要执行的任务. 多线 ...

  7. Java学习---多线程的学习

    基础知识 每个正在系统上运行的程序都是一个进程(process).每个进程包含一到多个线程(thread).进程也可能是整个程序或者是部分程序的动态执行. 线程是一组指令的集合,或者是程序的特殊段,它 ...

  8. Java学习多线程第一天

    内容介绍 Thread 线程创建 线程池 线程状态图 1 多线程 1.1     多线程介绍 学习多线程之前,我们先要了解几个关于多线程有关的概念. 进程:进程指正在运行的程序.确切的来说,当一个程序 ...

  9. java学习多线程之创建多线程一

    现在我们有这么一个需求,就是在主线程在运行的同时,我们想做其他的任务,这个时候我们就用到了多线程.那么如何创建多线程,我们知道在系统当中qq的多线程创建是由操作系统来完成的,那么如果我们想在java当 ...

随机推荐

  1. 大型网站的架构设计问题—-大型高并发高负载网站的系

    转载:http://www.cnblogs.com/cxd4321/archive/2010/11/24/1886301.html 随着中国大型IT企业信息化速度的加快,大部分应用的数据量和访问量都急 ...

  2. 关于sqlserver 2008 远程导入表数据

    /*不同服务器数据库之间的数据操作*/ --创建链接服务器 exec sp_addlinkedserver   'ITSV ', ' ', 'SQLOLEDB ', '远程服务器名或ip地址 ' ex ...

  3. 【转】浅析Windows编程的剪贴板

    摘要: 本文对Windows剪贴板机制作了深入.全面的阐述,具体内容包括:文本.位图.DSP.自定义格式剪贴板的使用和多数据项和延迟提交技术. 关键词: VC++6.0: 剪贴板机制:数据格式:延迟提 ...

  4. mysql的分区技术

    一.概述 当 MySQL的总记录数超过了100万后,会出现性能的大幅度下降吗?答案是肯定的,但是,性 能下降>的比率不一而同,要看系统的架构.应用程序.还有>包括索引.服务器硬件等多种因素 ...

  5. html-----014---统一资源定位器

    HTML 统一资源定位器 URL 可以由单词组成,比如 “w3school.com.cn”,或者是因特网协议(IP)地址:192.168.1.253.大多数人在网上冲浪时,会键入网址的域名,因为名称比 ...

  6. PHP pear安装出现 Warning: require_once(Structures/Graph.php)...错误

    今天在WINDOWS安装pear,一路无阻很顺利安装完成,接着想安装下pear email包来玩下,但接下来却报: Warning: require_once(Structures/Graph.php ...

  7. 尝试设计LFSR加密器,并用CAP4验证随机性

    在CPA4软件中有提供设计LFSR加密器的功能: 输入LFSR的大小,初始密钥,还有反馈密钥. 点击Set Key后点击Show LFSR 观察LFSR,发现初始密钥是1101,转成十六进制是D,反馈 ...

  8. mybatis()

    ---------------------------------mysql分页---------------------------------- public void selectList(in ...

  9. GCC --verbose选项, -lpthread 和-pthread的区别

    verbose的意思是冗长的,繁杂的.顾名思义,gcc --verbose 的意思就是打印出编译连接时的详细信息. 参考stackoverflow中的文章结合自己机器的信息给出分析(其实也就是翻译了一 ...

  10. eclipse汉化安装

    http://hi.baidu.com/rankabc/item/b07e03466550e4ce1381dac4 Eclipse汉化方法 网上搜了很多教程,步骤都不够详细,因此写一篇傻瓜版教程让新手 ...