Как иметь дело с несколькими нитями в одном классе?

Нити часто разрабатываются двумя способами (см. явские обучающие программы): или расширяя класс Нити или осуществляя Работоспособный класс. Так или иначе Вы должны определить то, что будет бежать в нити.

Я проектировал класс, адаптер к ресурсу онлайн, который восстанавливает различные виды информации. Этот класс состоит из методов как getInformationOfTypeA () и getInformationOfTypeB (). Оба содержат кодекс, чтобы соединиться с ресурсами онлайн, таким образом, обе потребности, которые будут пронизываться, чтобы избежать тупиков.

Вопрос: как я должен проектировать это? Я могу сделать это как ниже, но тогда я могу только осуществить один метод:

public class OnlineResourceAdapter implements Runnable {

  public void run() {
      //get stuff from resource
      getInformationOfTypeA();
  }

  public static void main(String args[]) {
      (new Thread(new OnlineResourceAdapter ())).start();
  }

  public void getInformationOfTypeA(){
      //get information of type A
  }

  public void getInformationOfTypeB(){
      //get information of type B
  }

}

Иначе был бы, создав отдельные классы для каждого метода, но это кажется неестественным мне.

Btw: я разрабатываю свое приложение в j2me

ОБНОВЛЕНИЕ:

Благодаря Вашим ответам я думаю, что это больше всего подходит, чтобы использовать что-то как следующее как методы:

Что Вы думаете об этом:

public class OnlineResourceAdapter{
    public void getInformationOfTypeA(){
        Thread t = new Thread(new Runnable() {           
            public void run() { 
                //do stuff here
            } 
        });
        t.start();
    }

    public void getInformationOfTypeB(){
        Thread t = new Thread(new Runnable() {           
            public void run() { 
                //do stuff here
            } 
        });
        t.start();
    }
}

Что Вы думаете об этом?

9
задан Sean Owen 17 January 2010 в 23:44
поделиться

6 ответов

Два анонимных внутренних классов, таких как Торбьерн Равн Андерсен, предложил смутно выше, работает. Вот пример кода:

public class OnlineResourceAdapter {

    public final Runnable typeA;
    public final Runnable typeB;

    public OnlineResourceAdapter() {
        typeA = new Runnable() {
            public void run() {
                OnlineResourceAdapter.this.getInformationOfTypeA();
            }
        };
        typeB = new Runnable() {
            public void run() {
                OnlineResourceAdapter.this.getInformationOfTypeB();
                // one can use a non-final typed variable
                // to store, which then<1>
            }
        };
    }

    public static void main(String args[]) {
        OnlineResourceAdapter x = new OnlineResourceAdapter();
        new Thread(x.typeA).start(); // start A
        new Thread(x.typeB).start(); // start B
        // <1>can be accessed here.
    }

    public void getInformationOfTypeA(){
        // get information of type A
        // return the data or directly store in OnlineResourceAdapter.
    }

    public void getInformationOfTypeB(){
        //get information of type B
    }

}

Редактирование: Да, вы предлагаете путь - это хороший способ. Вы даже можете сделать методы статичными. Вы можете использовать «Onlineresourceadapter.this». Чтобы получить доступ к другим переменным для хранения результатов.

4
ответ дан 4 December 2019 в 19:33
поделиться

Для каждого класса создают анонимный класс на основе Runnable. Это позволит вам делать то, что вам нужно сделать внутри метода Run ().

1
ответ дан 4 December 2019 в 19:33
поделиться

Используйте анонимные классы типа Callable (которые, в отличие от Runnable , могут возвращать значения) и выполнить их с помощью исполнителя . Если логика для извлечения информации и информации BINGS очень похожа, вы, конечно, Refactor, что и используйте один, параметризующий внутренний класс озвонов.

Я не уверен, что Callable и Executor являются частью J2ME Spec, хотя. В стандартной Java я бы пошел на прокси прокси в любом случае и инкапсулировать внешний ресурс в качестве интерфейса.

public class AsyncMethodsTest {

    public class OnlineResourceAdapter {

        private final ExecutorService executor = Executors.newFixedThreadPool(2);

        public String getInformationOfTypeA() throws InterruptedException, ExecutionException,
                TimeoutException {
            Callable<String> callable = new Callable<String>() {
                @Override
                public String call() throws Exception {
                    // Connect to external resource
                    Thread.sleep(500);
                    return "A";
                }

            };
            Future<String> submit = executor.submit(callable);
            return submit.get(1000, TimeUnit.MILLISECONDS);
        }

        public String getInformationOfTypeB() throws InterruptedException, ExecutionException,
                TimeoutException {
            Callable<String> callable = new Callable<String>() {
                @Override
                public String call() throws Exception {
                    // Connect to external resource
                    Thread.sleep(1500);
                    return "B";
                }

            };
            Future<String> submit = executor.submit(callable);
            return submit.get(1000, TimeUnit.MILLISECONDS);
        }

    }

    @Test
    public void testMethodCalls() throws Exception {
        OnlineResourceAdapter adapter = new OnlineResourceAdapter();
        assertNotNull(adapter.getInformationOfTypeA());
        assertNotNull(adapter.getInformationOfTypeB());
    }
}
-1
ответ дан 4 December 2019 в 19:33
поделиться

Я не понимаю, почему вам не нравится идея создания нескольких классов, учитывая Java, не поддерживает функции более высокого порядка, а изменяемая часть вашего кода является алгоритмом.

Но если вы хотели одной реализации Onlineresourceadapter , вы можете использовать шаблон стратегии и сделать что-то вроде этого:

public interface InformationGetter {
  public void getInformation();
}

public class OnlineResourceAdapter implements Runnable {
  private final InformationGetter informationGetter;

  public OnlineResourceAdapter(InformationGetter i) {
    this.informationGetter = i;
  }

  public void run() {
      //get stuff from resource
      i.getInformation();
  }
}

, а затем, конечно, вы создадите как можно больше реализации информации как вам нужно.

Приходите подумать об этом, оглядываясь назад на этот подход, OnlineReSourceadapter Теперь на самом деле не добавляет ничего, кроме принятия информации Runnable. Поэтому, если у вас не имеет некоторой неотъемлемой причины не, я бы сказал, просто имел информацию REVILE Runnable напрямую.

1
ответ дан 4 December 2019 в 19:33
поделиться

Мне кажется, что у тебя должно быть два разных класса: InformationOfTypeAFetcher и InformationOfTypeBFetcher, каждый из которых должен реализовывать Runnable. Каждый из них может иметь ссылку на экземпляр вашего OnlineResourceAdapter (или что-то подобное), но если они делают разные вещи, то они должны быть разными классами.

6
ответ дан 4 December 2019 в 19:33
поделиться

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

public class OnlineResourceAdapter implements Runnable
{
    private string resourceType;

    public OnlineResourceAdapter(string resourceType)
    {
        this.resourceType = resourceType;
    }

    public void run() {
        if (resourceType.equals("A") {
            getInformationOfTypeA();
        } else {
            // etc..
        }
    }

    public void getInformationOfTypeA(){
        //get information of type A
    }

    public void getInformationOfTypeB(){
        //get information of type B
    }
}

Использование:

(new Thread(new OnlineResourceAdapter("A"))).start();
1
ответ дан 4 December 2019 в 19:33
поделиться
Другие вопросы по тегам:

Похожие вопросы: