使用java的Runtime.getRuntime().exec()在linux机子上,找到hadoop的安装路径,目的是为了在hadoop的tem里面找到数据块。刚开始使用的时候一直是没有输出,后来查找资料知道会需要同时读取标准输出流与错误输出流缓冲区数据,因为操作系统缓冲区大小有限制,不及时处理会导致缓冲区占满而挂住,这种问题发生在于开发人员对该接口不了解而引发Bug。
解决方法是将其作为两个线程任务扔到线程池里面执行,使用CompletionService获取多线程返回值。用里面的future.get()方法。
参考资料:
(总结)线程实现的三种方式(Thread、Runable、Callable)
https://blog.csdn.net/Mr_Tony/article/details/78952520
Runtime.getRuntime().exec()执行阻塞问题解决
https://blog.csdn.net/nms312/article/details/39050945?utm_source=tuicool
使用CompletionService获取多线程返回值
https://blog.csdn.net/cbjcry/article/details/70154897
上代码:
package demo2
import java.util.concurrent.CompletionService;
import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.ThreadPoolExecutor;
public class ExecuteScript
{
private static String value = null;
public static void main(String[] args)
{
String[] cmd = new String[] { "/bin/sh", "-c","whereis hadoop"};
ececute(cmd);
System.out.println(value);
}
static void ececute(String[] cmd)
{
Process proc = null;
int result = -1;
try
{
ThreadPoolExecutor es = (ThreadPoolExecutor) Executors.newCachedThreadPool();
CompletionService<String> cs = new ExecutorCompletionService<String>(es);
proc = Runtime.getRuntime().exec(cmd);
StreamReader error = new StreamReader(proc.getErrorStream(), "Error");
StreamReader output = new StreamReader(proc.getInputStream(), "Output");
//ExecutorService executorService = Executors.newSingleThreadExecutor();
cs.submit(error);//添加第一个任务
cs.submit(output);//添加第二个任务
//executorService.shutdown();
Future<String> future = cs.take();
//String value = future.get();
value = future.get();
System.out.println("结果:"+value);
result = proc.waitFor();
}
catch (Exception e)
{
e.printStackTrace();
}
finally
{
proc.destroy();
}
}
}
package demo2;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.concurrent.Callable;
public class StreamReader implements Callable<String>
{
public String path = null;
public String getPath() {
return path;
}
InputStream is;
String type;
StreamReader(){}
StreamReader(InputStream is, String type)
{
this.is = is;
this.type = type;
}
public void close(InputStreamReader isr, BufferedReader br)
{
if (null != br)
{
try
{
br.close();
}
catch (IOException e)
{
br = null;
}
}
if (null != isr)
{
try
{
isr.close();
}
catch (IOException e)
{
isr = null;
}
}
}
@Override
public String call() throws Exception {
InputStreamReader isr = null;
BufferedReader br = null;
try
{
isr = new InputStreamReader(is);
br = new BufferedReader(isr);
String line = null;
while ((line = br.readLine()) != null)
{
//path = line;
System.out.println(line);
if(line != null) {
this.path = line;
return "线程返回值是:"+path;
}
}
}
catch (IOException ioe)
{
ioe.printStackTrace();
}
finally
{
close(isr, br);
}
System.out.println(Thread.currentThread().getName());//pool-1-thread-1
return "线程返回值是:"+this.path;
}
}
这是我的第一篇博客,发现自己的基础还相当薄弱,纪念一下这个认知的时刻,如有错误还望指正。谢谢!