1

Тема: Чи потрібна у даному випадку синхронізація?

Задача така - потік виконує список завдань, які додаються динамічно до цього списку.Якщо потік їх виконав всі, то він засинає до находження наступних.

class MyThr implements Runnable
{
    private List<String> tasks;
    private Thread owner=null;
    private boolean stop=false;
    public MyThr(List<String> tasks)
    {
        this.tasks=tasks;
    }
    public void Stop()
    {
        stop=true;
    }
    @Override
    public void run() 
    {
        // TODO Auto-generated method stub
        for(;;)
        {
            if(stop==true){break;}
            if(owner==null)
            {
                owner=Thread.currentThread();
            }
            
            if(tasks.isEmpty()==false)
            {
                String task=(String) tasks.get(0);
                tasks.remove(task);
                System.out.println(task);

                try 
                {
                    owner.sleep(2000);//імітація затримки,під час обміну даними через сіть
                } 
                catch (InterruptedException e){                }
            }
            else
            {
                try 
                {
                    owner.sleep(Long.MAX_VALUE);
                } 
                catch (InterruptedException e){                }
            }
        }
    }
    
}

public class Main 
{

    public static void main(String[] args) 
    {
        // TODO Auto-generated method stub
        List<String> tasks=new ArrayList<String>();
        tasks.add("1111");
        tasks.add("2222");
        tasks.add("3333");
        tasks.add("4444");
        MyThr mthr=new MyThr(tasks);
        Thread thr=new Thread(mthr);
        thr.start();
        for(int i=0;i<10;i++)
        {
            tasks.add(String.valueOf(i+1)+" !!!! ");
        }
        if(thr.getState() == java.lang.Thread.State.TIMED_WAITING)
        {
            thr.interrupt();
        }
        try
        {
            System.in.read();
        } 
        catch (IOException e) {        }
        mthr.Stop();
        thr.interrupt();
    }

}

ЧИ обов'язково синхронізувати доступ до  List<String> ?

2

Re: Чи потрібна у даному випадку синхронізація?

ЧИ обов'язково синхронізувати доступ до  List<String> ?

Обов'язково. А саме, юзати щось на кшталт CopyOnWriteArrayList.
Детальніша відповідь тут.

P.S.

if(tasks.isEmpty()==false)

- прирівнювати до false - зайве. Достатньо

!tasks.isEmpty()

3

Re: Чи потрібна у даному випадку синхронізація?

Базове правило таке: в кожен об'єкт може або писати один потік, або читати з нього декілька. Або виключне, тобто не одночасно. Якщо треба перемкнутися між потоками, які працюють із об'єктом - то треба синхронізовувати.
Зараз мучаюся із rust-ом, там це правило прямо в мову вбудоване.

4

Re: Чи потрібна у даному випадку синхронізація?

DOP написав:

ЧИ обов'язково синхронізувати доступ до  List<String> ?

Обов'язково. А саме, юзати щось на кшталт CopyOnWriteArrayList.

Чи правильно я зрозумів що CopyOnWriteArrayList::add synchronized метод ?

5

Re: Чи потрібна у даному випадку синхронізація?

cheappi386 написав:
DOP написав:

ЧИ обов'язково синхронізувати доступ до  List<String> ?

Обов'язково. А саме, юзати щось на кшталт CopyOnWriteArrayList.

Чи правильно я зрозумів що CopyOnWriteArrayList::add synchronized метод ?

Більш точніше, на мою думку, thread safe method(як і вся колекція).