Hey all,

I just started recently to use threading in Java. My situation is as follows:

The main thread waits for certain events and then assigns items to be processed to different threads.
I do have 3 workers running, processing the items assigned to them. Each thread holds an ArrayList containing the items to be processed.
So in short the main thread adds items, the worker threads do process the list of items assigned to them. A worker always processes the first item of its list and removes it then (during writing I do recognize that ArrayList might not be the best container for my situation [suggestions welcome]).

I do know that ArrayList is not thread safe and thus I am asking myself if I could run into problems.
For now I would say that my code is safe without any locking or synchronizing, since each thread only removes its own items sequentially and only the main thread is adding items. Is that correct?
If yes what would be conditions which would get my code unsafe? I would guess for example two main threads adding items to the workers?

Below you can find a minimal example illustrating what I am doing.

Thank you for your input.

Java Code:
import java.util.ArrayList;
import java.util.Random;
import java.util.UUID;


public class Worker extends Thread
{
	static final Random rand = new Random();
	
	public static void main(String[] args)
	{		
		int nT = 3;
		Worker[] w = new Worker[nT];
		
		for(int i = 0; i < nT; ++i) //create nT workers
		{
			w[i] = new Worker(i);
			w[i].start();
		}
				
		while(true) //feed workers with items
		{
			w[rand.nextInt(nT)].addItem(UUID.randomUUID().toString());
			try {
				Thread.sleep(rand.nextInt(100));
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
	
	private ArrayList<String> list = new ArrayList<String>();
	private int id;
	
	public Worker(int id)
	{
		this.id = id;
	}

	public void run()
	{
		while(true)
		{
			if(list.size() > 0)
			{
				processFirstItem();
				try {
					Thread.sleep(rand.nextInt(1000));
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
			
		}
    }
	
	public void addItem(String item)
	{
		log("item " + item + " added");
		list.add(item);
	}
	
	public void processFirstItem()
	{
		//do something
		log("item " + list.get(0) + " processed");
		list.remove(0);
	}
	
	public void log(String msg)
	{
		System.out.println("thread " + id + ": " + msg);
	}
}