lundi 8 juin 2020

Concurrency - write a program in which multiple threads add the same amount of elements to list

So I am supposed to write a program, in which multiple threads add some number of items to a list. I was given two interfaces that I should implement. The number added is a sum of two previous numbers added (like Fibonacci series)

public interface Main
{
    List<Integer> sum(int count, int threadCount, int firstElement, int secondElement);
}

and

public interface Sum extends Runnable
{
    //how many elements each thread should add
    int getHowMany();

    List<Integer> getList();
}

So I thought of doing it this way: I create a class DefaultSum, which implements Sum interface, implement methods from it, and in the run() method I would call a method actually adding elements to list. This is my DefaultSum class

public class DefaultSum implements Sum {
    DefaultMain main = new DefaultMain();
    Thread t;

    DefaultSum() {
        t = new Thread(this);
        t.start();

    }

    @Override
    public void run() {
        try {
            System.out.println("im working" + " " + Thread.currentThread().getName());
            int count = getHowMany();
            List<Integer> list = getList();
            int firstElement = list.get(list.size() - 2);
            int secondElement = list.get(list.size() - 1);
            Method methodall = main.getClass().getDeclaredMethod("sum", int.class, int.class, int.class, int.class);
            methodall.invoke(main, count, main.threadCount, firstElement, secondElement);

            System.out.println(firstElement);
            System.out.println(secondElement);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }

    }

    @Override
    public int getHowMany() {

        try {
            Field[] fields = DefaultMain.class.getFields();
            for (int i = 0; i < fields.length; i++) {
                Object val = fields[i].get(main);
                if (fields[i].getName().equalsIgnoreCase("count")) {
                    int number = (Integer) val;
                    return number;

                }
            }

        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return -1;
    }

    @Override
    public List<Integer> getList() {

        List<Integer> lista = null;
        try {
            Field[] fields = DefaultMain.class.getFields();
            for (int i = 0; i < fields.length; i++) {
                Object val = fields[i].get(main);
                if (fields[i].getName().equalsIgnoreCase("list")) {
                    lista = (List<Integer>) val;
                    return lista;
                }
            }

        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return null;
    }
}

And my main class, DefaultMain, where the number of items added is given and user can decide how many threads he wants to work on this list.

public class DefaultMain implements Main {
    static int firstElement = 0;
    static int secondElement = 1;
    static int count = 10; // amount of added elements
    public static  List<Integer> list = new ArrayList<Integer>();

    int threadCount; //amount of threads that add elements

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

        list.add(firstElement);
        list.add(secondElement);
        System.out.println("how many threads");
        Scanner sc = new Scanner(System.in);
        int threadCount = sc.nextInt();
        System.out.println(list);

        DefaultSum[] ds = new DefaultSum[threadCount];
        for (int j = 0; j < threadCount; j++) {
            ds[j] = new DefaultSum();

        }

    }

    public synchronized List<Integer> sum(int count, int threadCount, int firstElement, int secondElement) {
        this.list = list;
        for (int i = 2; i < count; i++) {
            int adder = firstElement + secondElement;
            list.add(adder);
            firstElement = secondElement;
            secondElement = adder;
        }

        return list;
    }
}

I tried running this program multiple times, however, it seems that the list is not updated after first two elements are added. Seems that methods getHowMany() and getList() work fine, I'm not sure what could be wrong, I'll appreciate any answer, this problem has been bugging me for some time now.





Aucun commentaire:

Enregistrer un commentaire