java同步多线程问题
我只是写了一些代码来测试多线程如何同步,但我无法得到预期的结果。代码可以启动3个线程,但只有一个线程来处理共享资源。我的代码有什么问题java同步多线程问题,java,multithreading,synchronized,Java,Multithreading,Synchronized,我只是写了一些代码来测试多线程如何同步,但我无法得到预期的结果。代码可以启动3个线程,但只有一个线程来处理共享资源。我的代码有什么问题 class ThreadDemo1{ public static void main (String[] args){ MultiThread tt = new MultiThread(); new Thread(tt).start(); new Thread(tt).start(); new Thr
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--);
}
}
}
}
}
你拿着锁睡觉。如果要这样做,就没有理由使用多线程
public void run () {
System.out.println(Thread.currentThread().getName());
while(tickets > 0) {
synchronized(_lock) {
if (tickets > 0) {
System.out.println(Thread.currentThread().getName() + " is selling " + tickets--);
}
}
try {
Thread.sleep(10);
} catch (Exception e) {
}
}
}
我猜睡眠
是您处理的占位符。如果可能,您应该在同步块内执行检查和减量操作,但在同步块外执行冗长的处理
为了让锁和多线程对您有用,您必须确保synchronized
代码花费尽可能少的时间,因为这是一次只能由一个线程运行的代码
在您的代码中,唯一不能有效实现单线程的是您的第一个System.println
仅供参考,考虑到这一点,如果您的打印报表准确但可能有误,那么最好是:
public void run () {
System.out.println(Thread.currentThread().getName());
while(tickets > 0) {
int oldTickets = 0;
synchronized(_lock) {
if (tickets > 0) {
oldTickets = tickets--;
}
}
if(oldTickets > 0) {
System.out.println(Thread.currentThread().getName() + " is selling " + oldTickets);
try {
Thread.sleep(10);
} catch (InterruptedException e) {
}
}
}
}
[1]首先,在您发布的代码中有几个不好的做法/错误: (1) 最好将Lock对象设置为singleton。您可以使用静态字段对象或类本身(因为内存中只有一个类) (2) 将
while(true){…}
从同步块中取出。在您的代码中,如果第一个线程获得锁,它将处理所有票据,并且不会停止。
应该让每个线程在循环的每次迭代中都尝试获得锁
(3) 对于线程.sleep(10)
,我猜您的意思是线程正在做一些繁重的工作。但将此类代码放在同步块(或另一个名称:critical region)中并不是一个好的做法。因为一次只有一个线程可以访问同步块。代码的行为类似于单线程程序,因为其他线程必须等待当前运行的线程完成其任务
请参见以下代码:
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*
类而不是synchronized block,它是无锁的,将为您带来更好的性能。例如:
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) {}
}
}
}
锁必须是静态的你有一些奇怪的格式。。。采用更标准的格式将有助于您编写更清晰的代码,并让我们理解您的代码。例如,你在原来的帖子中根本不清楚是否缺少右大括号,我因为建议将锁对象设为静态对象而被责骂。还可以将lock对象传递给每个可运行对象,以便在其上进行同步。我觉得有必要阻止别人挨骂。:)
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) {}
}
}
}