售票窗口多线程问题,比较俩种代码

问题描述

售票窗口多线程问题,比较俩种代码

代码一:
public class TestThread {

public static void main(String[] args) {
    // TODO Auto-generated method stub
     Test t=new Test();
     Test t1=new Test();
     Test t2=new Test();
     t.start();
     t1.start();
     t2.start();
}

}
//class Test extends Thread
class Test extends Thread
{
private int num=50;
private Dog myDog=new Dog();
public void run()
{

    while(true)
    {
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        synchronized (myDog) {
            if(num>0)
            {
                System.out.println(this.getName()+"正在售出第"+num+"张票");
                num--;
            }else
            {
                break;
            }
        }

    }

}

}
class Dog
{
}

**代码二:**
public class TestThread {
public static void main(String[] args) {
    //定义一个售票窗口
    TicketWindow tw1=new TicketWindow();

    //使用三个线程同时启动
    Thread t1=new Thread(tw1);
    Thread t2=new Thread(tw1);
    Thread t3=new Thread(tw1);

    t1.start();
    t2.start();
    t3.start();
}

}

//售票窗口类
class TicketWindow implements Runnable {
//共有2000张票
private int nums=2000;
private Dog myDog=new Dog();

public void run() {
    while(true){
        //出票速度是1秒出一张
        try {
            Thread.sleep(1000);
        } catch (Exception e) {
            e.printStackTrace();
        }

        //认为if else要保证其原子性
        //先判断是否还有票
        synchronized(myDog){
             if(nums>0){
                //显示售票信息
                //Thread.currentThread().getName()得到当前线程的名字
System.out.println(Thread.currentThread().getName()+"正在售出第"+nums+"张票");
                    nums--;
            }else{
                //售票结束
                 break;
             }
        }
     }
 }

}

class Dog{
}

俩种代码的区别是什么?求大神指点。运行结果完全不同。

解决方案

实现多线程有2中一种是继承Thread,一种是实现Runnable。一般情况下比较推荐实现Runnable接口。
因为java中一个类只能继承一个父类,所以受局限性。还有一个重要的是实现Runnable接口的线程资源可以共享。
根据上面购票系统解释一下的话一共的票数是固定的 只是用多线程并发的去卖票。
所以TicketWindow可以共享给多个线程购买。但是如果继承Thread的话首先得将2000个票分给每一个线程,每一个线程只能固定卖自己所有的,资源不被共享。
如果理解了麻烦请采纳,为了好理解我全是手写的~

解决方案二:

谢谢,今天看书看到了。俩种实现多线程的区别。票数存在共享与否的问题。所以代码1中,每张票卖了三次。

时间: 2024-09-19 09:04:16

售票窗口多线程问题,比较俩种代码的相关文章

在IOS中为什么使用多线程及多线程实现的三种方法_IOS

多线程是一个比较轻量级的方法来实现单个应用程序内多个代码执行路径. 在系统级别内,程序并排执行,程序分配到每个程序的执行时间是基于该程序的所需时间和其他程序的所需时间来决定的. 然而,在每个程序内部,存在一个或者多个执行线程,它同时或在一个几乎同时发生的方式里执行不同的任务. 概要提示: iPhone中的线程应用并不是无节制的,官方给出的资料显示,iPhone OS下的主线程的堆栈大小是1M,第二个线程开始就是512KB,并且该值不能通过编译器开关或线程API函数来更改,只有主线程有直接修改UI

JAVA多线程实现的三种方式

JAVA多线程实现 JAVA多线程实现方式主要有三种:继承Thread类.实现Runnable接口.使用ExecutorService.Callable.Future实现有返回结果的多线程.其中前两种方式线程执行完后都没有返回值,只有最后一种是带返回值的. 前两种大家应该都熟悉,第三种不太常用,但有时面试时会问到所以我在这里写下. 继承Thread类实现多线程 继承Thread类的方法尽管被我列为一种多线程实现方式,但Thread本质上也是实现了Runnable接口的一个实例,它代表一个线程的实

详细解读JAVA多线程实现的三种方式_java

最近在做代码优化时学习和研究了下JAVA多线程的使用,看了菜鸟们的见解后做了下总结. 1.继承Thread类实现多线程 继承Thread类的方法尽管被我列为一种多线程实现方式,但Thread本质上也是实现了Runnable接口的一个实例,它代表一个线程的实例,并且,启动线程的唯一方法就是通过Thread类的start()实例方法.start()方法是一个native方法,它将启动一个新线程,并执行run()方法.这种方式实现多线程很简单,通过自己的类直接extend Thread,并复写run(

SQL数据库实现递归查询的几种代码方法

SQL数据库实现递归查询的几种代码方法 表结构 ProductCategory CategoryID,Level,ParentCategoryID 数据 1,1,-1 2,1,-1 3,2,1 4,3,3 5,2,2 6,4,5 T-SQL WITH CategoryTemp(CategoryID,ParentCategoryID)--临时表用来保存查到的Category ( SELECT CategoryID,ParentCategoryID FROM ProductCategory WHER

求解-分析俩段代码else的最后两句是干什么?求大神指点

问题描述 分析俩段代码else的最后两句是干什么?求大神指点 下边俩段代码,else里的最后两句为什么他俩不一样啊?第一段代码else的最后两句是干什么? 第二段代码else的最后两句是干什么? public String getList() throws Exception { quZhengGuiZeList = dao.getList(TrainingOrCompetitionID); if(quZhengGuiZeList.size()>0){ quZhengGuiZe=quZhengG

提供第三种代码生成方式——通过自定义BuildProvider为ASP.NET提供代码生成

之前写了一些关于代码生成的文章,提供了两种不同方式的代码生成解决方案,即CodeDOM+Custom Tool和T4.对于ASP.NET应用,你还有第三种选择--自定义BuildProvider.[文中涉及的源代码从这里下载] 目录 一.BuildProvider是什么? 二.将XML表示的消息转换成VB.NET或者C#代码 三.将XML转换成CodeDOM 四.自定义BuildProvider 五.BuildProvider的应用 一.BuildProvider是什么? 对于ASP.NET应用

创建后台任务的两种代码模式

创建后台任务的两种代码模式 后台任务是每个App都需要的一些行为,毕竟主线程是大爷,拖不起,伤不起,脏活累活都只能在不见天日的后台去做. 最简单的后台任务,可以说是直接开一个线程就可以了,或者说来个Service,再开个线程.但这些并不是官方认证的最佳实践,实际上,Google早就考虑到了这一点,并把这些需求进行了封装,给我们提供了非常好的后台任务解决方案,并在Training上进行了讲解: 官网镇楼: https://developer.android.com/training/best-ba

Map俩种遍历方式

Map本身没有迭代器因而在遍历其中元素时需要采取新的措施,在JDK中提供了俩种方法 keySet Set<K> keySet() 返回此映射中包含的键的 Set 视图.该 set 受映射支持,所以对映射的更改可在此 set 中反映出来,反之亦然.如果对该 set 进行迭代的同时修改了映射(通过迭代器自己的 remove 操作除外),则迭代结果是不确定的.set 支持元素移除,通过Iterator.remove.Set.remove.removeAll.retainAll 和 clear 操作可

directx9 0-跪求DirectX全屏(无窗口)游戏的截屏代码

问题描述 跪求DirectX全屏(无窗口)游戏的截屏代码 跪求DirectX全屏(无窗口)游戏的截屏代码,dx9和dx11的都行,C++和C#的都行,不需要其它功能,只要能截下全屏的图就行!迫切! 解决方案 窗口全屏代码