多线程java同步多线程问题
我只是写了一些代码来测试多线程如何同步,但我无法得到预期的结果。代码可以启动3个线程,但只能启动一个线程来处理共享资源。我的代码有什么问题
class ThreadDemo1{
public static void main (String[] args){
MultiThread tt = new MultiThread();
new Thread(tt).start();
new Thread(tt).start();
new Thread(tt).start();
}
}
class MultiThread implements Runnable {
int tickets = 100;
Object _lock = new Object();
public void run () {
System.out.println(Thread.currentThread().getName());
synchronized(_lock) {
while (true) {
if (tickets>0) {
try {
Thread.sleep(10);
} catch (Exception e) {}
System.out.println(Thread.currentThread().getName() + " is selling "+tickets--);
}
}
}
}
}
# 1 楼答案
[1]首先,在您发布的代码中有几个不好的做法/错误:
(1)Lock对象最好是singleton。您可以使用静态字段对象或类本身(因为内存中只有一个类)
(2)将
while(true) {...}
从同步块中取出。在您的代码中,如果第一个线程获得锁,它将处理所有票据,并且不会停止。 应该让每个线程在循环的每次迭代中都尝试获得锁(3)对于
Thread.sleep(10)
,我猜您的意思是线程正在做一些繁重的工作。但将此类代码放在同步块(或另一个名称:critical region)中并不是一个好的做法。因为一次只有一个线程可以访问同步块。代码的行为类似于单线程程序,因为其他线程必须等待当前运行的线程完成其任务请参见以下代码:
[2]其次,如果您只想在拾取票据时同步线程。尝试使用
Atomic*
类而不是同步块,它没有锁,将为您带来更好的性能。例如:# 2 楼答案
你拿着锁睡觉。如果要这样做,就没有理由使用多线程
我猜
sleep
是您处理的占位符。如果可能,您应该在同步块内执行检查和减量操作,但在同步块外执行冗长的处理为了让锁和多线程对您有用,您必须确保
synchronized
代码占用的时间尽可能少,因为这是一次只能由一个线程运行的代码在您的代码中,唯一不能有效实现单线程的是您的第一个
System.println
仅供参考,考虑到这一点,如果您的打印报表准确但可能有误,那么最好是: