线程同步 卖票问题 三个车站卖七张票

问题描述

线程同步 卖票问题 三个车站卖七张票

正确的写法:public class mainclass {
public static void main(String[] args) {
Train A=new Train();
Train B=new Train();
Train C=new Train();
A.start();
B.start();
C.start();

}
}
class Train extends Thread{
public static int ticket=7;
public void run(){
{
A();
}
}
public synchronized void A(){
while (ticket>0){
System.out.println("第"+this.getName()+"站卖出第"+ticket--+"张票");
}
}

}
出现问题的写法:public class mainclass {
public static void main(String[] args) {
Train A=new Train();
Train B=new Train();
Train C=new Train();
A.start();
B.start();
C.start();

}
}
class Train extends Thread{
public static int ticket=7;
public void run(){
{
A();
}
}
public synchronized void A(){
while (ticket>0){
System.out.println("第"+this.getName()+"站卖出第"+ticket+"张票");
ticket--;
}
}

}
在A()函数之中ticket--的位置不同却出现了两种结果。一种将ticket--写在输出语句里,结果正确,但一种写在输出语句之外就会出现线程同步问题,可是我已经在函数前面加了synchronized,为什么会这样,按理来说两者应该一样啊。

解决方案

首先,你的线程类Train类使用的public 方法的synchronized,锁匙当前this对象,所以你的三个线程都是使用各种的this对象,根本不存在锁竞争问题,都是各买各的票,彼此无影响的。
其次,你想让三个线程卖票,有竞争的话,那么必须使用同一个锁对象,这个锁对象必须是从外界传递过去的。
建议重新编写Train类,关联一个成员变量,然后同步使用这个锁对象,参考如下:

 public class Train extends Thread{
    private Ticket ticket;

    public Train(Ticket ticket){
        this.ticket = ticket;
    }

    public void run(){
        while(true){
            sale();

            //卖完一张票后休眠,让其他线程也卖
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }

    public void sale(){
        synchronized (ticket) {
            int count = ticket.getCount();
            if(count<=0){
                System.out.println("票已经卖完了啦。。。");
                return;
            }

            System.out.println(Thread.currentThread().getName()+"售出一张票。");
        }
    }
}

Ticket类:

 public class Ticket {
    private int count;
    public Ticket(int count){
        this.count = count;
    }
    public int getCount() {
        return count;
    }
    public void setCount(int count) {
        this.count = count;
    }
}
时间: 2024-10-30 11:17:37

线程同步 卖票问题 三个车站卖七张票的相关文章

C#中的线程(二)线程同步

Keywords:C# 线程Source:http://www.albahari.com/threading/Author: Joe AlbahariTranslator: Swanky WuPublished: http://www.cnblogs.com/txw1958/Download:http://www.albahari.info/threading/threading.pdf    第二部分:线程同步基础   同步要领 下面的表格列展了.NET对协调或同步线程动作的可用的工具: 简易

巴士管家怎么买两张票 巴士管家买两张票方法

巴士管家是一款非常方便的汽车购票软件,有用户不清楚如何买票,不清楚怎么购买两张票,今天小编为大家介绍一下购买两张票的方法,一起来看吧. 购买方法: 1.需要一张一张的购买,如果是两个人的话,需要添加两张身份证,每次分开购买. 2.一张身份证同一车次只能购买一张票,只有不同的车次和时间才可以购买两张票. PS:购买车票后需要到车站的取票机或者窗口取票才可以上车. 以上就是巴士管家购买两张票的方法,希望对大家有所帮助.

C#编程总结(三)线程同步

在应用程序中使用多个线程的一个好处是每个线程都可以异步执行.对于 Windows 应用程序,耗时 的任务可以在后台执行,而使应用程序窗口和控件保持响应.对于服务器应用程序,多线程处理提供了 用不同线程处理每个传入请求的能力.否则,在完全满足前一个请求之前,将无法处理每个新请求.然 而,线程的异步特性意味着必须协调对资源(如文件句柄.网络连接和内存)的访问.否则,两个或更 多的线程可能在同一时间访问相同的资源,而每个线程都不知道其他线程的操作. "如果觉得有用,请帮顶! 如果有不足之处,欢迎拍砖!

基本线程同步(三)在同步的类里安排独立属性

在同步的类里安排独立属性 当你使用synchronized关键字来保护代码块时,你必须通过一个对象的引用作为参数.通常,你将会使用this关键字来引用执行该方法的对象,但是你也可以使用其他对象引用.通常情况下,这些对象被创建只有这个目的.比如,你在一个类中有被多个线程共享的两个独立属性.你必须同步访问每个变量,如果有一个线程访问一个属性和另一个线程在同一时刻访问另一个属性,这是没有问题的. 在这个指南中,你将学习如何解决这种情况的一个例子,编程模拟一家电影院有两个屏幕和两个售票处.当一个售票处出

浅谈.NET下的多线程和并行计算(三)线程同步基础 上

其实,如果线程都是很独立的,不涉及到任何资源访问的,那么这些毫无干扰的线程不会产生什么问 题.但是在实际应用中我们的线程总是涉及到资源访问的,而且往往涉及到共享资源的访问,那么就产生 了线程同步的问题.一直觉得线程同步这个名词很奇怪,字面上看同步就是使得步调一致,线程同步是不 是就是让线程步调一致的访问资源呢?事实上反了,线程同步恰巧是让线程不同时去访问资源而是去按照 我们期望的顺序依次访问资源(是同步资源访问的行为而不是同步同时访问资源).一句话,多个线程( 不仅仅局限于相同进程)如果需要访问

第三章-线程同步工具(引言)

章节提要: 并发地访问资源的控制 并发地访问多个副本资源的控制 等待多个并发事件 在一个相同点同步任务 并发的阶段性任务的运行 并发地阶段性任务的阶段改变的控制 在并发任务间改变数据 介绍 在第二章基本的线程同步中,我们学习了同步和critical section的内容.基本上,当多个并发任务共享一个资源时就称为同步,例如:一个对象或者一个对象的属性.访问这个资源的代码块称为:临界区. 如果机制没有使用恰当,那么可能会导致错误的结果,或者数据不一致,又或者出现异常情况.所以必须采取java语言提

Java 线程同步 synchronized

先来看一个不带线程同步的例子,这个例子很简单,只是让两个线程输出同样的内容,并不做其他的事, 所以,线程同步在这里体现的并不明显. import java.util.Date; public class ThreadTest extends Thread{ int pauseTime; String name; /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method s

java-多线程 | 线程安全和线程同步

线程安全 线程安全就是多线程访问时,采用了加锁机制,当一个线程访问该类的某个数据时,进行保护,其他线程不能进行访问直到该线程读取完,其他线程才可使用.不会出现数据不一致或者数据污染. 线程不安全就是不提供数据访问保护,有可能出现多个线程先后更改数据造成所得到的数据是脏数据. 概述 如果你的代码所在的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码.如果每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的,就是线程安全的. 或者说:一个类或者程序所提供的接口对于

线程同步的一个问题,求高手指导

问题描述 线程同步的一个问题,求高手指导 public class TestTicket{ public static void main(String[] args){ SellTickets st = new SellTickets(); Thread t1 = new Thread(st,"窗口1--"); Thread t2 = new Thread(st,"窗口2--"); Thread t3 = new Thread(st,"窗口3--&quo