Безопасно ли создавать экземпляр объекта из потока внешнего класса, если он выполняется локально? - PullRequest
0 голосов
/ 02 февраля 2020

Итак, я узнаю о параллелизме, безопасности потоков и других связанных темах с помощью программы, которую я пытаюсь адаптировать к многопоточной модели.

Вот иллюстрация того, что я делаю.

public class readerThread implements Runnable {

    private static BlockQueue<String> iqueue
    private static BlockingQueue<Object> oqueue
    private static ThreadLocal<java.util.ArrayList<File>> fileList = new ThreadLocal<java.util.ArrayList<File>>();  
    private static int FILE_BATCH_SIZE = 50;

    public void run() {
    fileList.set(new ArrayList<File>());
    ThreadLocal<Integer> i = new ThreadLocal<Integer>();    
    i.set(1);

        for (int y = i.get(); i<1000000; i.set(y++)) {

            try {

                File datafile = new File(iqueue.poll(86400, TimeUnit.SECONDS));

            } catch (InterruptedException e) {           
                e.printStackTrace();
            }

            if (datafile == null || datafile == POISION) {
                break;
            }

            fileList.get().add(datafile);
            ...
            ...

            if (fileList.get().size() == FILE_BATCH_SIZE || (iqueue.peek() == null) || (iqueue.peek() == POISON) ) {
                parseAndWrite();
                fileList.get().clear();         

            }






        }

    }



    public void parseAndWrite() {

        for (File f : fileList.get()) {
            Long fileTs = f.lastModified()
            String fileName = String.valueOf(f);

            Filelog filelog = new Filelog()
            Asset asset = new Asset()

            Parser parser = new Parser(f);
            // Parser returns an Asset
            asset = parser.parse()
            String assetTag = asset.getAssetTag();      


            filelog.setTimeStamp(fileTs);
            filelog.setFileName(fileName);
            filelog.setAssetTag(assetTag);
            filelog.setProcessed(false);

            HibernateWrapper.commit(filelog);

            oqueue.put(asset);


            .....
            .....


        }

    }



}

Пожалуйста, игнорируйте любые очевидные ошибки в примере, так как он был поспешно собран. По сути, несколько readerThreads извлекают файлы из очереди блокировки, извлекают данные как объект и записывают объект в базу данных, используя Hibernate. Давайте на минутку предположим, что HibernateWrapper на 100% безопасен для потоков; поскольку данные в объекте ресурса связаны с файлами, взятыми из очереди, и поскольку каждый поток работает с отдельным файлом, является ли он потокобезопасным? Прости меня, если моя терминология выключена. По сути, я считаю, что мой предыдущий код был ненадежным, поскольку я наблюдал несколько примеров, когда строки записанных данных были связаны с неправильными объектами (например, в файле foo есть метка актива бара).

1 Ответ

0 голосов
/ 02 февраля 2020

Безопасность потоков - это проблема, когда между потоками существует общее состояние. Если ваш код таков, что каждый поток имеет свой собственный набор переменных, то этот код является потокобезопасным. Это сложнее, чем кажется из-за возможного общего состояния для других функций или сторонних библиотек, которые вы вызываете, потому что они могут вводить общее состояние для потоков.

Использование fileList в качестве локального потока правильно, но, похоже, это не нужно, потому что вы можете передать его методу parseAndWrite в качестве аргумента.

Использование локального потока i не нужно, поскольку это переменная стека, и каждая нить будет иметь свою собственную копию.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...