[1]首先,在您的发布代码中有几个不好的练习/错误:
(1)锁定对象最好是单身。你可以使用一个静态字段对象或类本身(由于只有一个类在存储器中)
Object _lock = new Object();
private static final Object _lock = new Object();
(2)将while(true) {...}
出同步块的。在你的代码中,如果第一个线程获得锁定,它将处理所有票据并且不会停止。 应该让每个线程都尝试在循环的每次迭代中获得Lock。
(3)对于Thread.sleep(10)
,我想你的意思是线程正在做一些繁重的工作。但将这种代码放入同步块(或另一个名称:关键区域)不是一个好习惯。因为一次只有一个线程可以访问同步块。你的代码行为就像是一个单线程程序,因为其他线程必须等到当前正在运行的线程完成其工作。
请参见下面的代码:
public class ThreadDemo1 {
public static void main(String[] args) {
MultiThread tt = new MultiThread();
new Thread(tt).start();
new Thread(tt).start();
new Thread(tt).start();
}
}
public class MultiThread implements Runnable {
private static int tickets = 100;
private static final Object _lock = new Object();
public void run() {
System.out.println(Thread.currentThread().getName());
while (tickets > 0) {
try {
synchronized (_lock) {
if (tickets > 0) {
System.out.println(Thread.currentThread().getName() + " is selling " + tickets--);
}
}
Thread.sleep(10);
} catch (Exception e) {
}
}
}
}
[2]第二,如果你只是想线程在采摘门票同步。尝试使用Atomic*
类而不是同步块,它是无锁,并会带来更好的性能。例如:
import java.util.concurrent.atomic.AtomicInteger;
public class MultiThreadAtomic implements Runnable {
private static AtomicInteger tickets = new AtomicInteger(100);
public void run() {
System.out.println(Thread.currentThread().getName());
int ticketsRemaining = 0;
while ((ticketsRemaining = tickets.getAndDecrement()) > 0) {
System.out.println(Thread.currentThread().getName() + " is selling " + ticketsRemaining);
try {
Thread.sleep(10);
}
catch(InterruptedException ie) {}
}
}
}
锁必须是静态 –
你有一些古怪的格式有...采用更标准的格式化会帮你写更清晰的代码,我们理解你的代码。例如,你原来的帖子中遗漏了大括号,这完全不清楚。 – yshavit