2015-07-09 4 views
0

У меня есть класс InstanceFactory, который создает экземпляры определенного класса, назовем его классом instance. Эти экземпляры создаются в методе main(). В этом случае класс I в настоящее время звонит, как instance.init(), instance.put(), instance.stop().выполнить класс в своей собственной теме

Поскольку все работает в одном потоке, и я обнаружил некоторые проблемы с производительностью, я хочу попробовать запустить экземпляр в отдельном потоке.

Какие изменения я должен внести в класс экземпляра, чтобы позволить ему работать в отдельных потоках? Смогу ли я по-прежнему выполнять одни и те же вызовы, например. instance.init()?

Update (код добавляется):

InstanceFactory instanceFactory = new InstanceFactory(); 
try (Instance instance = instanceFactory.create()) { 
    instance.init(); 
    instance.doStuff(); 
    while ((input = reader.readNext()) != null) { 
     instance.put(input); 
    } 
} 

экземпляр должен работать в своем собственном потоке.

+3

показать использовать некоторый код –

+0

'instance.start()' должен запустить новый поток, если он 'extends Thread' или' реализует Runnable'. –

+0

добавлен код. – beta

ответ

1

Вы могли бы, вероятно, использовать ExecutorService

Если instance.put() потокобезопасно, вы можете заменить Executors.newSingleThreadExecutor(); с Executors.newCachedThreadPool(), например.

InstanceFactory instanceFactory = new InstanceFactory(); 
ExecutorService executor = Executors.newSingleThreadExecutor(); 
try (Instance instance = instanceFactory.create()) { 
    instance.init(); 
    instance.doStuff(); 
    while ((input = reader.readNext()) != null) { 
     executor.execute(new Runnable() { 
      @Override 
      public void run() { 
       instance.put(input); 
      } 
     }); 
    } 
    executor.shutdown(); 
    executor.awaitTermination(1, TimeUnit.MINUTES); 
} 

Примечание: Это непроверенный код.

+0

Ваш ответ по-прежнему действителен после этого комментария? http://stackoverflow.com/questions/31315314/execute-class-in-its-own-thread/31316001#comment50619459_31315314 – beta

+1

@beta Да, это так. –

+0

Какую пользу я получу, заменив 'newSingleThreadExecutor()' на 'newCachedThreadPool()'? – beta

2

Executors.newSingleThreadExecutor() создает только один рабочего потока, так что вы будете иметь один основного потока + один рабочего потока с очередью в FIFO из post() задач. Если ваш метод post() равен thread-safety, вы должны использовать Executors.newCachedThreadPool(), который создает столько потоков при необходимости.

InstanceFactory instanceFactory = new InstanceFactory(); 
ExecutorService executor = Executors.newCachedThreadPool(); 
try (Instance instance = instanceFactory.create()) { 
    instance.init(); 
    instance.doStuff(); 
    while ((input = reader.readNext()) != null) { 
     executor.execute(new Runnable() { 
      @Override 
      public void run() { 
       instance.put(input); 
      } 
     }); 
    } 
} finally { 
    executor.shutdown(); 
} 

Я советую вам прочитать official documentation и некоторые guides о ExecutorService.

+0

другой ответ (http://stackoverflow.com/a/31316001/973158) говорит, что он является потокобезопасным, если я использую «Исполнители».newSingleThreadExecutor() 'вместо' Executors.newCachedThreadPool() '. – beta

+0

@beta, не объявляйте метод put() как синхронизированный, потому что только один поток получит разрешение на доступ к нему. Вы должны объявить как синхронизированные методы, которые, например, увеличивают размер массива. –

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