从线程返回值

时间:2011-03-09 14:38:05

标签: blackberry java-me

我在下面有一个线程类,它从一个url读取一个文件,然后将结果存储在一个公共静态变量中,以便可以从其他类访问它。有没有比这更好的了?

由于

public class ReadContent implements Runnable{

    private HttpConnection connection;
    private InputStream inputStream;
    private String url;

    public ReadContent(String url){
        this.url = url;
    }

    public void run() {
        readContentURL();
    }

    private void readContentURL() {

        try {   
                connection = (HttpConnection)Connector.open(url);
                connection.setRequestMethod(HttpConnection.GET);
                connection.setRequestProperty("Connection", "close");
                inputStream = connection.openDataInputStream();

            //  inputStream = getClass().getResourceAsStream(url);
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                int c ;
                while (true) {
                    c = inputStream.read();
                    if (c == -1)
                        break;
                    baos.write(c);
                }

                SavedJSON.result = new JSONObject(new String(baos.toByteArray()));

            } 
            catch(Exception e){
                e.printStackTrace();
            }   
    }

}

这是我提出的解决方案 -

public class MyFuture{ 
      private final Object lock = new Object();

      private JSONObject value;
      public void set(JSONObject t){
          value = t;
          synchronized(lock){
              value = t;
              lock.notifyAll();  
          }
      }

      public JSONObject get(){
         synchronized(lock){
              while(value == null)
                try {
                    lock.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

              return value;
         }

      }    
    }

public class SavedJSON {

    public static MyFuture result;
    }

public class ReadContent implements Runnable{

    private HttpConnection connection;
    private InputStream inputStream;
    private String url;

    public ReadContent(String url){
        this.url = url;
    }

    public void run() {
        readContentURL();
    }

    private void readContentURL() {

        try {   
            int len = 0;
                connection = (HttpConnection)Connector.open(url);
                connection.setRequestMethod(HttpConnection.GET);
            //  connection.setRequestProperty("Connection", "close");
                inputStream = connection.openDataInputStream();

            //  inputStream = getClass().getResourceAsStream(url);
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                int c ;
                while (true) {
                    c = inputStream.read();
                    if (c == -1)
                        break;
                    ++len;
                    baos.write(c);
                }

                SavedJSON.result.set(new JSONObject(new String(baos.toByteArray(), 0, len, "utf-8")));

            } 
            catch(Exception e){
                e.printStackTrace();
            }   
    }

}

5 个答案:

答案 0 :(得分:2)

由于你不能使用Callable(我假设你也不能使用Future),你可以尝试创建自己的Future。它相对简单:

public class MyFuture<T>{ // can you not use generics either?
  private final Object lock = new Object();

  private T value;
  public void set(T t){
      synchronized(lock){
          value = t;
          lock.notifyAll();  
      }
  }
  public T get(){
     synchronized(lock){
          while(value == null) lock.wait();

          return value;
     }

  }    
}

现在您可以SavedJSON.result成为MyFuture,只要有人想要价值并需要等待,他们就可以简单地拨打SavedJSON.result.get();并且该集合显然可以是SavedJSON.result.set(new JSONObject(new String(baos.toByteArray()))); < / p>

编辑:

这是为了解决您的评论和编辑问题。

首先:您可能希望传播中断的异常。通常线程会尝试使用中断来“停止”其他线程。您可以在方法上添加throws声明,抛出运行时异常或只返回null值。

第二:你不应该在synchronized块之外有value = t。由于各种原因,这可能会失败。你应该删除该行,它看起来很不错。

答案 1 :(得分:1)

查看Callable接口(对于返回值的Runnable)以及用于各种不同线程池实现的Executors类。

答案 2 :(得分:1)

对于你的情况,我建议实现一个回调,如下所示:

回调:

public interface SimpleCallback {
    public void onReceive(JSONObject data);
}

调用:

...
SimpleCallback callback = new SimpleCallback() { 
    public void onReceive(JSONObject data) {
        // do something
    }
}
new Thread(new ReadContent(url, callback));
...

主题:

...
    // read input stream
    callback.onReceive(new JSONObject(new String(baos.toByteArray())));
} catch(Exception e){
...
希望有所帮助。

答案 3 :(得分:0)

答案 4 :(得分:0)

您的结果未同步。您应该改进SavedJSON类,以便创建getResult()和setResult()方法并使它们同步。 wait()和notify()方法也应该对你有帮助。