2016-04-02 64 views
2

在提供实时库存的应用程序中运行有两个Web服务。我必须编写一个java多线程程序来从这两个接口读取清单并计算总库存。如何使用多线程来聚合两个Web服务?

前提条件:两个线程都必须毫不迟延地启动。

我试着用下面的代码来解决这个问题。请检查并告诉我这是否正确。还有另一种可用的替代方法。

package com.app.thread; 

public class InventoryThread { 

    public static void main(String a[]) throws InterruptedException { 

     Inventory inv = new Inventory(); 
     InventoryInterface1 i1 = new InventoryInterface1(inv); 
     InventoryInterface2 i2 = new InventoryInterface2(inv); 

     Thread t1 = new Thread(i1, "T1"); 
     Thread t2 = new Thread(i2, "T2"); 

     t1.start(); 
     t2.start(); 

     t1.join(); 
     t2.join(); 

     System.out.println(inv.getInventory()); 
    } 
} 

class Inventory { 

    private long inventory; 

    public long getInventory() { 
     return inventory; 
    } 

    public void setInventory(long inventory) { 
     this.inventory = inventory; 
    } 
} 

class InventoryInterface1 implements Runnable { 

    private Inventory inv; 

    public InventoryInterface1(Inventory inv) { 
     this.inv = inv; 
    } 

    public void run() { 
     System.out.println(Thread.currentThread().getName() + " running"); 
     synchronized (inv) {    
      System.out.println(Thread.currentThread().getName() + " updates inventory"); 
      inv.setInventory(inv.getInventory() + 100);   
     } 
    } 
} 

class InventoryInterface2 implements Runnable { 
    private Inventory inv; 

    public InventoryInterface2(Inventory inv) { 
     this.inv = inv; 
    } 

    public void run() { 
     System.out.println(Thread.currentThread().getName() + " running"); 
     synchronized (inv) { 
      try { 
       System.out.println(Thread.currentThread().getName() + " waiting.."); 
       while(inv.getInventory() <= 0){ 
        inv.wait(); 
       }    
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
      System.out.println(Thread.currentThread().getName() + " updates inventory"); 
      inv.setInventory(inv.getInventory() + 200); 
      System.out.println(Thread.currentThread().getName() + " notifies"); 
      inv.notifyAll(); 
     } 
    } 
} 
+0

我建议你先阅读并发教程。在你的例子中有一些错误,在本质上需要一个教程,如答案 –

+0

@loannis我正在学习Java的并发性,并希望获得专家输入的问题,我被要求解决。谢谢! – Vel

回答

1

变化Inventory.inventory变为AtomicLong。你不会需要同步化的Inventory比如在InventoryInterface1 & InventoryInterface2

class Inventory { 

    private AtomicLong inventory = new AtomicLong(); 

    public long getInventory() { 
     return inventory.longValue(); 
    } 

    public void incrementInventory(long inventory) { 
     inventory.addAndGet(inventory); 
    } 
} 

问题呀是读取和写入到Javalong不需要是原子的。 AtomicLong的addAndGet是一个原子操作。

这里被修改InventoryInterface1InventoryInterface2

class InventoryInterface1 implements Runnable { 

    private Inventory inv; 

    public InventoryInterface1(Inventory inv) { 
     this.inv = inv; 
    } 

    public void run() { 
     System.out.println(Thread.currentThread().getName() + " running"); 
     System.out.println(Thread.currentThread().getName() + " updates inventory"); 
     inv.incrementInventory(100);   

    } 
} 



    class InventoryInterface2 implements Runnable { 

    private Inventory inv; 

    public InventoryInterface2(Inventory inv) { 
     this.inv = inv; 
    } 

    public void run() { 
     System.out.println(Thread.currentThread().getName() + " running"); 
     System.out.println(Thread.currentThread().getName() + " updates inventory"); 
     inv.incrementInventory(200); 
    } 
} 
+0

这很有帮助。需要在Inventory类中创建AtomicLong对象以避免空指针异常。谢谢。 – Vel

+1

更新了帖子。谢谢。 – Sanj

0

我不知道你会看到如果双方你Runnable线程都在为他们的整个执行同步以来唯一一个可以同时启动多线程的任何性能改进。一般的方法看起来是正确的,但我只是试图限制你的同步,当你实际访问共享内存。

更新

看起来你也可能有其中一个线程持有锁同步,并等待其无法执行,直到锁被释放的其他线程死锁情况。在您致电inv.wait()之前,您可以释放锁,但是您确实应该在访问inv时使用更细粒度的同步。

你真的关心哪个线程先执行?如果你这样做,你可能不想使用多线程,如果你不这样做,你可能会从InventoryInterface2中删除wait()

class InventoryInterface2 implements Runnable { 
    private Inventory inv; 

    public InventoryInterface2(Inventory inv) { 
     this.inv = inv; 
    } 

    public void run() { 
     System.out.println(Thread.currentThread().getName() + " running"); 
     synchronized (inv) { 
     System.out.println(Thread.currentThread().getName() + " updates inventory"); 
     inv.setInventory(inv.getInventory() + 200); 
     System.out.println(Thread.currentThread().getName() + " notifies"); 
     inv.notifyAll(); 
    } 

} 
+0

我添加了wait()进行线程间通信,所以不会发生死锁。我运行了你的改变,它也起作用。谢谢。 – Vel

相关问题