2015-06-27 7 views
0

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

private static final File CONFIG_FILE = new File("./config.json");; 
private static final ReadWriteLock READ_WRITE_LOCK = new ReentrantReadWriteLock(true); 
private static final Lock READ_LOCK = READ_WRITE_LOCK.readLock(); 
private static final Lock WRITE_LOCK = READ_WRITE_LOCK.writeLock(); 
... 
    public void write(JsonData data) { 
    Verifier.verifyNotNull(data,"data : null"); 
    Verifier.verifyNotNull(data.getData(),"JsonData data : null"); 
    Verifier.verifyNotEmpty(data.getIdentifier(),"JsonData identifier : empty"); 

    Writer writer = null; 
    Gson gson = null; 
     try { 
     WRITE_LOCK.lock(); 
     writer = new FileWriter(CONFIG_FILE); 

     gson = new GsonBuilder().setPrettyPrinting().create(); 
     gson.toJson(data, writer); 
     } 
     catch (IOException e) { 
      e.printStackTrace(); 
     } 
     finally { 
     try { 
      if (writer != null) { 
       writer.flush(); 
       writer.close(); 
      } 
     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
     catch (RuntimeException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
     finally { 
      WRITE_LOCK.unlock(); 
     } 
     } 

Замок, показанный выше, представляет собой блокировку Reeentrant, предоставляемую библиотеками Java. Если я хочу, чтобы тестировать вышеуказанный метод безопасности потоков, как это проверить?

Просьба сообщить,

Спасибо!

+1

Для этого вам нужно несколько блоков try. Если 'writer.flush()' генерирует исключение, вы не освободите блокировку. –

+0

Здравствуйте, спасибо, что заметили это. Я переместил 'writer.flush()' в блок catch. Поскольку методы «.flush» и «.close» бросают «IOExceptions», я думаю, что блокировка будет выпущена в блоке catch для «IOException», показанного выше. Отредактировано код – Rookie

+0

Попробуйте вложить блоки try, чтобы у вас был внешний, посвященный только блокировке. Это позволяет избежать необходимости разблокировать в разных местах или быть удивленным ошибкой в ​​'flush()' бросать исключение RuntimeException', которое вы пропустили. –

ответ

1

Если вы введете либо объект Writer, либо объект Gson, вы можете предоставить макетную реализацию. Если вы издеваетесь над автором, сделайте так, чтобы методы write блокировались, чтобы они не закончили и не отпустили блокировку. Сделайте это в одном потоке. В другой, позвоните вашwrite метод снова. Наконец, в вашей «основной» тестовой нити закрутите, пока состояние заблокированной нити не будет Thread.State.BLOCKED. Если он никогда не блокируется или заканчивается, вы терпите неудачу. Как только вы увидите, что он заблокирован, отпустите первый поток (CountDownLatch подходит для этого) и убедитесь, что оба потока завершены.

+0

Спасибо за ваш комментарий, я смотрю на Blitzer clas от Jmock. Этого будет достаточно? http://www.jmock.org/threading-blitzer.html – Rookie

+0

Это зависит от того, почему вы блокируете. Если это потому, что Gson не является потокобезопасным, то, вероятно. Если это связано с тем, что вы не хотите писать в файл одновременно, это зависит в большей степени от вашей ОС и блокировки файлов. –

+0

Я блокируюсь, чтобы только один поток мог писать за раз. проблема с читателем-автором в основном. Это файл конфигурации, поэтому я не хочу, чтобы несколько потоков пытались записать в него. – Rookie

Смежные вопросы