#java #multithreading #class #object
#java #многопоточность #класс #объект
Вопрос:
Допустим, у меня есть класс, который содержит список отсортированных чисел.
Объект имеет функцию get, поэтому я могу видеть частные переменные внутри класса (в данном случае, массив)
Если я передам объект потоку, как мне получить доступ к функции get класса?
eg
Thread t1 = new testclass();
t1.start();
t1.getvalue() ; ??
Я еще ничего не закодировал, все еще на этапе разработки моего задания
Ответ №1:
Обычно в Java люди используют Runnable
вместо вывода из Thread
:
class MyThing implements Runnable {
private int x;
public void run() {
x = 10;
}
public int getX() { return x; }
}
MyThing thing = new MyThing();
Thread t = new Thread(thing);
t.start(); // The thread starts and calls MyThing::run() in itself
t.join(); // wait for t to finish
System.out.println(t.getX());
В a нет ничего особенного, Runnable
помимо интерфейса — вы могли бы так же легко вызвать thing.run()
напрямую, за исключением того, что это будет выполняться в вашем собственном потоке.
Комментарии:
1. EJSE, пункт 68: Отдавать предпочтение исполнителям и задачам, а не потокам. Вместо выполнения потока t = new Thread(thing);t.start();t.join(); сделайте это: Executors.newSingleThreadExecutor().submit(thing).get()
2. Я сделал так, и у меня не получилось. я не распознаю свой метод, объявленный в MyThing.
Ответ №2:
Вы хотели Runnable / Thread, который может дать вам результат после выполнения некоторой работы?
Я рекомендую вам заменить Thread / Runnable на Callable и отправить его в ExecutorService.
java.util.concurrent.Callable c = new java.util.concurrent.Callable() {
@Override
public Object call() throws Exception {
int result = 0;
// e.g.
// 1. do some work here
// 2. update result
return resu<
}
};
java.util.concurrent.ExecutorService threadpool
= java.util.concurrent.Executors.newSingleThreadExecutor();
java.util.concurrent.Future future = threadpool.submit(c);
Object result = null;
try {
result = future.get(5, java.util.concurrent.TimeUnit.SECONDS);
} catch (Exception e) {
System.err.println("ERROR!");
e.printStackTrace();
}
System.out.println("RESULT : " result);
Ответ №3:
Не совсем.
testclass t1 = new testclass();
t1.start();
t1.getvalue();
Комментарии:
1. поправьте меня, если я ошибаюсь, но разве это не просто обычный доступ к классу? Я планирую передавать объекты
2. Ну и что? То, что класс является потоковым, является внутренней деталью реализации. Вызывающим не нужно беспокоиться об этом. (Если бы они это сделали, как бы вы изменили класс с threaded на not threaded или наоборот, не изменяя весь код, который обращался к нему?)
3. Здесь я согласен с @DavidSchwartz. Любая блокировка / постановка в очередь / ожидание / любой другой сигнал, который должен произойти внутри средства получения, чтобы любой старый поток мог вызвать его из любого места, получали действительный результат.
Ответ №4:
Предполагая, что другой синтаксис правильный, ваш код не будет компилироваться, потому что t1 является объектом класса Thread, а класс Thread не имеет метода getvalue() . Вы не можете вызывать методы testclass непосредственно из объекта thread.
Как только вы вызовете t1.start(), будет выполнен метод run() тестового класса. Итак, если вы хотите вызвать getvalue(), вы должны вызвать его в методе run() и делать там все, что вы хотите, или вы должны вызвать метод getvalue() из объекта testclass.
Внутри метода run тестового класса:
public void run() {
//Do whatever you want to when the thread starts here.
System.out.println(Thread.currentThread().getName());
this.getvalue(); //This will call the getvalue() method of the test class.
}