Round robin a list in multithreaded environment

时间:2016-05-11 11:32:54

标签: java multithreading

I wrote a method which behaves as a round robin. Everytime someone calls it, it returns an integer from a list. When the end of the list is reached, it starts serving from the beginning.

I call this method from a stateless session bean.

The method is written in a util class like below

public final class MyUtil {

    private static int index;

    private MyUtil() {}

    public synchronized static int getNextInt() {
        Properties p = DBconfigModule.getProperties("key");
        List<String> list = Arrays.asList(((String) p.get("key")).split(","));
        try {
        if(index>=list.size()) {
           index = 0;
           next = list.get(0);
           index++;
        } else {
           next = list.get(index):
           index++;
        }
        } catch(final Exception e) {
             // log
             index = 0;
             next = list.get(0);
             index++;
        }
    return Integer.parseInt(next);
}

@Stateless
public class Usage {
    public int getNextInt() {
        return MyUtil.getNextInt();
    }
}

I am not sure how far what i have written is right and will work.

Can anyone tell me is this right and suggest me if it can be improved?

I do not want to use any 3pp libraries for this.

Thank you.

2 个答案:

答案 0 :(得分:1)

只有在永远不会更改list或使用相同的监视器访问列表synchronized时,您的代码才是正确的。

想象一下执行以下代码时会发生什么:

Thread 1                           Thread 2
-------------------                -----------------------
// index = 2
// list.size() = 3
if (index == list.size()) {

                                    // Removes first element
                                    // now list.size() = 2
                                    list.remove(0);


} else {
   // Will throw an exception
   // Because now list has size 2
   // and the third element (index 2) 
   // doesn't exists
   next = list.get(index);

答案 1 :(得分:0)

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger; 
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;


public class Counter {

    private ReadWriteLock listLock = new ReentrantReadWriteLock();

    private List<Integer> list = new ArrayList<>();

    private AtomicInteger indexCounter = new AtomicInteger(0);

    Integer getNextInt() {
        Lock readLock = listLock.readLock();
        try {
            if(list==null || list.size() == 0) {
                throw new IllegalStateException("Call setList() with  some values first.");
             }
             int index = indexCounter.incrementAndGet() % list.size();
             return list.get(index);
        } finally {
             readLock.unlock();
        }
    }

    void setList(List<Integer> newList) {
        Lock writeLock = listLock.writeLock();
        try {
            this.list = newList;
        } finally {
            writeLock.unlock();
        }
    }
}

类似的东西,非常粗略。