java 多线程的问题

李英杰 发布于 2012/12/11 16:09
阅读 316
收藏 0

这个程序 我的意图是想让三个线程一共卖100张票,但是每次运行的时候总是一个线程将100张票全部卖完。我已经在

run()方法中加入了Thread.sleep(1000);语句,感觉程序遇到这句时应该当前线程休眠,其他线程执行,不应该只有一

个线程执行呀?求高人指点?

您的任何帮助,我将不尽感激。

package com.cbd.zhixiang;


public class ThreadDemo
{
public static void main(String[] args)
{
        Ticket t = new Ticket();
        new Thread(t).start();
        new Thread(t).start();
        new Thread(t).start();
}
}


class Ticket  implements Runnable
{
private int count = 100;


Object obj = new Object();
public void run()
{
synchronized (obj)
{

while (count > 0)

try
{
Thread.sleep(1000);
} catch (InterruptedException e)
{
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "..."
+ count--);
}
}
}
}


加载中
0
灵羽
灵羽
class Ticket  implements Runnable
{
private int count = 100;

public void run()
{
Object obj = new Object(); 
synchronized (obj)
{

while (count > 0)
{ 
try
{
Thread.sleep(1000);
} catch (InterruptedException e)
{
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "..."
+ count--);
}
0
灵羽
灵羽
我觉得是这个同步锁加的位置有问题
0
j&a
j&a
同意楼上的观点,你想的。  Ticket t = new Ticket();
        new Thread(t).start();
        new Thread(t).start();

        new Thread(t).start();三个线程共用的是同一个对象,那么Object obj = new Object();这么一来,三个线程共用一把锁了。

楼上还是存在问题的,票的数量的改变,必需是线程安全的。

j&a
j&a
@古代瑞兽 这不是休眠的问题,那我问题你加这个休眠意义何在呢?
灵羽
灵羽
@古代瑞兽 @j&a如果去掉休眠,是不是就不存在问题了?
灵羽
灵羽
确实存在问题,这样线程不安全!
0
Grrrr
Grrrr

给你一个非阻塞的实现。这年头大家都非阻塞了。别折腾等待通知了。

票。很简单。初始总张数。


public class Ticket {
	private int total;

	public Ticket(int total) {
		super();
		this.total = total;
	}

	public int getTotal() {
		return total;
	}
}

非阻塞线程。买票。顺便说句,把票数调节的大点,否则会被一个线程全部买光。呵呵。

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicReference;

public class BuyTicket implements Runnable {
	private int got;
	private AtomicReference<Ticket> ticket;
	private boolean stop;
	private String name;
	public BuyTicket(AtomicReference<Ticket> ticket, String name) {
		super();
		this.ticket = ticket;
		this.name = name;
	}

	@Override
	public void run() {
		Thread.currentThread().setName(name);
		Buy: while (!stop) {
			try {
				Ticket current = null;
				Ticket next = null;
				do {
					current = ticket.get();
					if (current.getTotal() <= 0) {
						stop = true;
						break Buy;
					}
					next = new Ticket(current.getTotal() - 1);
				} while (!this.ticket.compareAndSet(current, next));
				this.got++;
			} catch (Exception e) {
				stop = true;
			}
		}
		System.out.println(Thread.currentThread().getName() + " got "
				+ this.got + " tickets");
	}

	public int getGot() {
		return got;
	}

	public void setGot(int got) {
		this.got = got;
	}

	public static void main(String args[]) {
		int total = 100000;
		ExecutorService executor = Executors.newFixedThreadPool(3);
		AtomicReference<Ticket> atomic = new AtomicReference<Ticket>(new Ticket(total));
		BuyTicket threadA = new BuyTicket(atomic, "A");
		BuyTicket threadB = new BuyTicket(atomic, "B");
		BuyTicket threadC = new BuyTicket(atomic, "C");
		System.out.println("Start ! There are " + atomic.get().getTotal() + " tickets left.");
		executor.execute(threadA);
		executor.execute(threadB);
		executor.execute(threadC);
		executor.shutdown();
		while (!executor.isTerminated()) {}
		System.out.println("Finished ! There are " + atomic.get().getTotal() + " tickets left.");
	}
}


0
冬日阳光
冬日阳光
你把count和obj放在线程内部怎么可能实现你要的功能呢。
返回顶部
顶部