2014-12-12 3 views
1

Я основной C# и начал развиваться на Java. У меня возникают проблемы, чтобы начать тему :((Java) Тема не будет выполнена

public class GetLocationInfo implements Runnable{ 

String address; 
double latitude; 
double longitude; 

public void run() { 
    HttpGet httpGet = new HttpGet("http://maps.google.com/maps/api/geocode/json?latlng=42.993504,-79.239167&sensor=false"); 
    //HttpGet httpGet = new HttpGet("http://maps.google.com/maps/api/geocode/json?latlng="+latitude+","+longitude+"&sensor=false"); 
    HttpClient client = new DefaultHttpClient(); 
    HttpResponse response; 


    try { 
     response = client.execute(httpGet); 
     HttpEntity entity = response.getEntity(); 
     InputStream stream = entity.getContent(); 

     JsonReader reader = new JsonReader(new InputStreamReader(stream, "UTF-8")); 

     reader.beginObject(); 
     while (reader.hasNext()) { 
      String name = reader.nextName(); 
      if (name.equals("formatted_address")) { 
       address = reader.nextString(); 
      } else 
       reader.skipValue(); 
     } 
     reader.endObject(); 
    } catch (ClientProtocolException e) { 
    } catch (IOException e) { 
    } 
} 


public String GetAddress(double lat, double lng) { 

    latitude = lat; 
    longitude = lng; 

    Thread thread = new Thread(this); 

    thread.start(); 
    return address; 
} 
} 

Я установил точки останова в методе переопределены Run(), и ничто не кажется, выполнить в этом методе. Если вы, ребята, можете помочь мне исправить это его было бы оценено.

Приветствия

+3

вы оставили блоки блокировки пустыми. Добавьте 'e.printStackTrace();' для каждого блока catch и проверьте, не выбрано ли исключение – Blackbelt

+3

, вы только что начали тему. Как вы ожидаете, что «адрес» будет заполнен? – njzk2

ответ

0

Я хотел бы предложить, что вы инкапсулируете «основной вид деятельности» в классе, который реализует Runnable или отозван (Если вы хотите, чтобы получить будущий результат). Используйте ThreadpoolExecutors представить задачи.

0

Спасибо, ребята за то, что ответы на некоторые вопросы. Хотя способ кодирования не может быть лучшей практикой, я нашел решение.

Просто создал конструктор для класса и начал там поток и сделал публичный открытый адрес строки.

public class GetLocationInfo implements Runnable{ 

public String address; 
double latitude; 
double longitude; 

public GetLocationInfo(double lat, double lng) { 

    latitude = lat; 
    longitude = lng; 

    Thread thread = new Thread(this); 

    thread.start(); 

} 

public void run() { 
    HttpGet httpGet = new HttpGet("http://maps.google.com/maps/api/geocode/json?latlng=42.993504,-79.239167&sensor=false"); 
    //HttpGet httpGet = new HttpGet("http://maps.google.com/maps/api/geocode/json?latlng="+latitude+","+longitude+"&sensor=false"); 
    HttpClient client = new DefaultHttpClient(); 
    HttpResponse response; 


    try { 
     response = client.execute(httpGet); 
     HttpEntity entity = response.getEntity(); 
     InputStream stream = entity.getContent(); 

     JsonReader reader = new JsonReader(new InputStreamReader(stream, "UTF-8")); 

     reader.beginObject(); 
     while (reader.hasNext()) { 
      String name = reader.nextName(); 
      if (name.equals("formatted_address")) { 
       address = reader.nextString(); 
      } else 
       reader.skipValue(); 
     } 
     reader.endObject(); 
    } catch (ClientProtocolException e) { 
    } catch (IOException e) { 
    } 
} 

}

+0

Существует несколько причин, по которым это не будет работать так, как вы этого хотите. Во-первых, как другой поток, который использует адрес, знает, когда он был заполнен? Вы просто собираетесь зацикливаться (отходы процессора)? Класс «FutureTask» был создан для этого сценария - https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/FutureTask.html. Вызов «get» на нем ждет завершения потока. Если вы этого не сделаете, вам, по крайней мере, нужно будет сделать поле вашего адреса «изменчивым». В противном случае java не гарантирует, что ваш другой поток сможет увидеть значение. – user384842

1

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

  1. Когда вы запускаете поток в методе GetAddress() это не означает, что она будет называть это немедленно запустить метод и просто приступить к возвращению вычисленного адреса, когда возвращается, как если бы вы вызвали метод run, не создавая новый поток. Вы бы даже не нуждались в другом потоке, если бы хотели этого. Когда вы запускаете второй поток, вы в основном сообщаете ОС, что есть новый поток, готовый к запуску, но он зависит от ОС, чтобы точно решить, когда действительно начнется код в этом потоке. Даже в среде с несколькими CPU/ядрами вы не можете предположить, что ядро ​​будет доступно в этой точке.
  2. Вы также не можете предположить, что основной поток остановится или приостановит его выполнение только потому, что он запустил другой поток. Основной поток может в конечном итоге прекратить выполнение в течение короткого времени, чтобы другие потоки могли выполняться, но только тогда, когда в системе недостаточно ядер для запуска всех потоков параллельно. В любом случае вы не можете предсказать, когда или произойдет это. Это означает, что после запуска нового потока гораздо вероятнее, что метод GetAddress() продолжит возвращать текущее значение адресной переменной своему вызывающему абоненту до завершения только что созданного потока или даже начать его метод run().
    Если вы не уверены в том, что истинно, то попробуйте вставить следующие строки после запуска нити:

    thread.start(); 
    try {    // Used just for demonstration purposes 
        thread.join(); // This block kills the parallelism of the second thread 
    } 
    return address; 
    

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

Так что же теперь?

У вас есть много способов борьбы с несколькими потоками, и я не могу рассказать вам, что является лучшим методом, не зная намного больше о вашем проекте; но я могу дать вам несколько направлений на очень простом примере.
Предположим, у вас есть программа с пользовательским интерфейсом, кнопка для получения адреса и текстовое поле, в которое будет записан адрес. Когда кто-то нажимает кнопку, вместо того, чтобы пытаться вычислить адрес одним выстрелом, вы вызываете метод вроде startRetrievingAddress(), в котором вы должны запустить рабочий поток и заполнить текстовое поле временным текстом, например "please wait...". В конце метода рабочего потока run() вы можете добавить код, чтобы заполнить текстовое поле окончательным результатом.
Еще лучший способ сделать это - создать класс рабочих потоков с поддержкой «слушателей», которые будут уведомлены, когда метод запуска будет выполнен с использованием адреса, чтобы они имели возможность иметь дело с результатами, как только они вычисляются. Затем вы зарегистрируете слушателя, в котором вы должны установить текстовое поле с вычисленным значением. Уверены, что есть еще лучшие способы сделать это, используя поток петлителя, чтобы иметь дело с сообщениями, выпущенными из рабочих потоков, и все, но я не могу назвать их всех здесь. Удачи!

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