以下代码旨在将产品对象的arraylist作为输入,为每个产品旋转线程(并将产品添加到arraylist'产品'),检查产品图像(product.imageURL)可用性,删除产品没有图像(从arraylist'产品中删除产品'),并返回带有图像的产品的arraylist。
package com.catgen.thread;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import com.catgen.Product;
import com.catgen.Utils;
public class ProductFilterThread extends Thread{
private Product product;
private List<Product> products = new ArrayList<Product>();
public ProductFilterThread(){
}
public ProductFilterThread(Product product){
this.product = product;
}
public synchronized void addProduct(Product product){
System.out.println("Before add: "+getProducts().size());
getProducts().add(product);
System.out.println("After add: "+getProducts().size());
}
public synchronized void removeProduct(Product product){
System.out.println("Before rem: "+getProducts().size());
getProducts().remove(product);
System.out.println("After rem: "+getProducts().size());
}
public synchronized List<Product> getProducts(){
return this.products;
}
public synchronized void setProducts(List<Product> products){
this.products = products;
}
public void run(){
boolean imageExists = Utils.fileExists(this.product.ImageURL);
if(!imageExists){
System.out.println(this.product.ImageURL);
removeProduct(this.product);
}
}
public List<Product> getProductsWithImageOnly(List<Product> products){
ProductFilterThread pft = null;
try{
List<ProductFilterThread> threads = new ArrayList<ProductFilterThread>();
for(Product product: products){
pft = new ProductFilterThread(product);
addProduct(product);
pft.start();
threads.add(pft);
}
Iterator<ProductFilterThread> threadsIter = threads.iterator();
while(threadsIter.hasNext()){
ProductFilterThread thread = threadsIter.next();
thread.join();
}
}catch(Exception e){
e.printStackTrace();
}
System.out.println("Total returned products = "+getProducts().size());
return getProducts();
}
}
致电声明:
displayProducts = new ProductFilterThread().getProductsWithImageOnly(displayProducts);
这里,当从getProductsWithImageOnly()中调用addProduct(product)时,getProducts()返回产品列表,但当线程调用removeProduct()方法时,情况并非如此(不返回任何产品),因此,没有图像的产品永远不会被删除。因此,无论所包含的产品是否有图像,模块都会返回所有产品。
这里有什么问题?
提前致谢。 詹姆斯。
答案 0 :(得分:0)
你在循环中每次迭代创建一个新的ProductFilterThread
:
new ProductFilterThread(product);
每个ProductFilterThread
都有自己的
private List<Product> products = new ArrayList<Product>();
所以当你使用run
方法时,
removeProduct(this.product);
您要从自己的products
实例中删除该产品。
我建议你以不同的方式设计它,或许给出线程应该使用的产品列表,作为ProductFilterThread
的参数:
private List<Product> products;
public ProductFilterThread(List<Product> products) {
this.products = products;
}
但我必须说,在使用像这样的多个线程时你应该仔细考虑。您需要仔细同步对数据结构的访问。
答案 1 :(得分:0)
如果您希望所有Filter Threads共享products
列表,那么您必须将其设置为静态。字段为confined to a single thread。
另一个评论 - 也许你应该重写products
的getter / setter方法来导出一个不可修改的列表并读取新创建的列表中的输入。否则,这可能是这种多线程设计中多次头痛的原因(只是想象另一个线程“获取”列表并在过滤处于活动状态时对其进行修改。)