2014-07-08 22 views
5

Aşağıdaki kodu bir varyasyonu vardır:Jenerik kodumu bu yöntem imzası ile nasıl uyumlu hale getirebilirim?

package com.test.package; 

import java.util.concurrent.BlockingQueue; 
import java.util.concurrent.PriorityBlockingQueue; 
import java.util.concurrent.ThreadPoolExecutor; 
import java.util.concurrent.TimeUnit; 

public class TestClass { 

    public static class MyRunnable implements Runnable { 

     @Override 
     public void run() { 
      System.out.println("Called"); 
     } 

    } 

    public void method() { 
     PriorityBlockingQueue<MyRunnable> queue = new PriorityBlockingQueue<MyRunnable>(); 
     method2(queue); 
    } 

    public void method2(BlockingQueue<? extends Runnable> queue) { 
     System.out.println(queue); 

     // Getting error here because BlockingQueue<? extends Runnable> is not a 
     // subtype of BlockingQueue<Runnable>. 
     ThreadPoolExecutor threadPool = new ThreadPoolExecutor(200, 200, 0L, 
      TimeUnit.MILLISECONDS, queue); 
    } 
} 

Ve gördüğünüz gibi, benim kuyruk ThreadPoolExecutor kurucu ile uyumlu değildir. Çevremde (BlockingQueue<Runnable>) için sıraya göre çalışmak için herhangi bir yolu var mı? Açıkçası Java Standart Kütüphanesi'ni ekleyemiyorum.

+3

Neden ilk etapta 'BlockingQueue ' kullanıyorsunuz? –

+0

Çünkü daha yüksek önceliğe sahip belirli runcables var. Karşılaştırma bölümünü örneğimde atladım çünkü bu soruyla ilgisiz. – Ztyx

+2

Eğer ilgisizse, o zaman belki 'PriorityBlockingQueue ' kullanabilirdiniz? Bunu yaparsanız 'PriorityBlockingQueue 'onları sıralamayı bırakmaz. –

cevap

7

Hayır, ve yapmamalısın.

, tabii ki, sadece MyRunnable s BlockingQueue<MyRunnable> içermelidir Sizin. Ama ThreadPoolExecutor bunu vermek sıraya keyfi Runnable görevleri gönderebilirler: execute(Runnable command) bakın.

Eğer bu gerçekleşirse, Sıranızdaki olmayan bir MyRunnable örneği olabilir. Daha sonra bu sıraya ait referanstan (BlockingQueue<MyRunnable> olarak yazılır) anket yapmaya çalışın ve bir ClassCastException olsun.

Basit bir örnek: parçacığı havuzu WhateverRunnable örneği sıradan çıkarma fırsatı bulduktan önce queue.poll() olursa Yukarıdaki kod bir istisna durumu

PriorityBlockingQueue<MyRunnable> queue = new PriorityBlockingQueue<>(); 
ThreadPoolExecutor threadPool = new ThreadPoolExecutor(200, 200, 0L, 
     TimeUnit.MILLISECONDS, queue); 
threadPool.execute(new WhateverRunnable()); 
MyRunnable myRunnable = queue.poll(); // this could throw ClassCastException 

.

+0

Yukarıdaki kod, örneğime göre ikinci satırdaki bir derleme hatası ile derlenmeyecektir. – Ztyx

+0

Evet, haklısın. Ama eğer açık oyuncu kadrosunu eklediysen - ve bahsettiğim sebeplerden dolayı tehlikeli olurdu. Bu nedenle, sistem size bunu yapmanıza izin vermez (en azından açık yayınlamadan ve hatta bile. Cast'in güvensiz olduğu konusunda sizi uyarır) – yshavit

İlgili konular