2016-04-02 14 views
2

Gerçek zamanlı envanter sağlayan bir uygulamada çalışan iki web hizmeti vardır. Bu iki arayüzden envanteri okumak ve toplam envanteri hesaplamak için bir java çok iş parçacığı programı yazmam gerekiyor.İki web hizmetini çoklu iş parçacığı kullanarak nasıl topluyorum?

Ön koşul: Her iki dişin de gecikme olmaksızın başlatılması gerekir.

Aşağıdaki kodu kullanarak bu soruna yaklaşmayı denedim. Lütfen bu doğru olup olmadığını kontrol edin ve bildirin. Ayrıca mevcut başka bir alternatif yaklaşım var. Eğer Runnable parçacığı hem tek bir seferde etkin olabilir çünkü onların tüm yürütülmesi için senkronize edilirse çoklu kullanım gelen herhangi bir iyileşme göreceksiniz eğer bilmiyorum

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

InventoryInterface1 ve InventoryInterface2 değiştirilir. Örneğinizde birkaç örnekte yanlışlık var. Özünde –

+0

@loannis gibi bir öğreticiye ihtiyaç var java'da eşzamanlılık öğreniyorum ve çözmek istediğim problem için uzman girişleri almak istedim. Teşekkürler! – Vel

cevap

1

Değişim Inventory.inventory. Eğer alışkanlık InventoryInterface1 & InventoryInterface2

class Inventory { 

    private AtomicLong inventory = new AtomicLong(); 

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

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

Problem Inventory örneğinde senkronizasyonu ihtiyaç Böylece okur ve Java yılında long için atomik olması gerekmez yazıyor olduğunu. AtomicLong'un addAndGet bir atomik işlemidir. İşte

Ben öncelikle bir eşzamanlılık öğretici okuma öneririm

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

Bu yardımcıdır. Boş gösterici istisnasını önlemek için, Envanter sınıfında AtomicLong nesnesinin oluşturulması gerekir. Teşekkürler. – Vel

+1

Yayını güncellendi. Teşekkürler. – Sanj

0

. Genel yaklaşım doğru görünüyor olsa da, senkronizasyonunuzu paylaşımlı belleğe eriştiğinizde sınırlamaya çalışacağım. Ayrıca parçacığı bir senkronizasyon kilidi tutarak ve aynı zamanda kilidi serbest kadar yürütemediğinden diğer iş parçacığı bekleyen bir kilitlenme durumu olabilir gibi

Güncelleme

görünüyor. inv.wait()'u aramadan önce kilidi serbest bırakabilirsiniz, ancak gerçekten erişim alanı çevresinde daha ince taneli bir eşitlemeyi inv'a kullanmalısınız.

Öncelikle hangi iş parçacığının yürütüleceğini önemsiyor musunuz? Eğer yaparsanız, çoklu iş parçacığı kullanmak istemeyebilirsiniz, yoksa, wait()'u InventoryInterface2'dan kaldırabilirsiniz. AtomicLong için

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

Inter thread iletişimi için wait() özelliğini ekledim, böylece kilitlenme oluşmaz. Değişikliklerinizi yaptım ve işe yarıyor. Teşekkürler. – Vel

İlgili konular