Issue accessing class variable from thread.

Posted by James on Stack Overflow See other posts from Stack Overflow or by James
Published on 2010-06-14T07:40:54Z Indexed on 2010/06/14 7:42 UTC
Read the original article Hit count: 256

Filed under:
|
|

Hello,

The code below is meant to take an arraylist of product objects as an input, spun thread for each product(and add the product to the arraylist 'products'), check product image(product.imageURL) availability, remove the products without images(remove the product from the arraylist 'products'), and return an arraylist of products with image available.

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();
    }
}

Calling statement:

displayProducts = new ProductFilterThread().getProductsWithImageOnly(displayProducts);

Here, when addProduct(product) is called from within getProductsWithImageOnly(), getProducts() returns the list of products, but that's not the case(no products are returned) when the method removeProduct() is called by a thread, because of which the products without images are never removed. As a result, all the products are returned by the module whether or not the contained products have images.

What can be the problem here?

Thanks in advance. James.

© Stack Overflow or respective owner

Related posts about java

Related posts about multithreading