java里用线程池执行调用python的任务
import org.slf4j.Logger;
import java.util.concurrent.*;
import java.io.BufferedReader;
import org.slf4j.LoggerFactory;
import java.io.InputStreamReader;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
public class ThreadPoolExecPython {
private static Logger logger = LoggerFactory.getLogger(ThreadPoolExecPythonCopy.class);
//创建线程池执行脚本任务
private static ExecutorService taskPool = new ThreadPoolExecutor(4,8,100L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>(1024),
new ThreadFactoryBuilder().setNameFormat("thread-pythonTask-runner-%d").build());
/**
* 用这个方法执行python的调用
* @param jobId 传递给python脚本的参数,这里只传递了一个参数在python里用sys.argv[1]可取参
* @throws Exception
*/
public void exec(String jobId) throws Exception {
PythonTaskCallable callable = new PythonTaskCallable(jobId);
//往线程池里面提交任务
Future<String> future = taskPool.submit(callable);
String rs = future.get();
logger.info("脚本任务{}执行完成",jobId);
}
//至于任务的执行看需求,如果需要拿到脚本的一些返回值或者调用完成之后做一些别的后续工作,用Callable回调比较合适
//如果只是调用后就不考虑别的因素,用Runnable就行
class PythonTaskCallable implements Callable<String> {
private String jobId;
public PythonTaskCallable(String jobId) {
this.jobId = jobId;
}
@Override
public String call() throws Exception {
String path = "python脚本文件的位置,用绝对不用考虑太多";
logger.info("脚本任务{}开始执行",jobId);
//String command = "python " + path; 不传参用字符串就行
//执行python的命令并传参,在python里可以用sys.argv获取参数列表,0对应的是path,sys.argv[1]取到的就是jobId
String[] command = new String[]{"python", path,jobId};
Process proc = Runtime.getRuntime().exec(command);
BufferedReader in = new BufferedReader(new InputStreamReader(proc.getInputStream()));
String line;
while ((line = in.readLine()) != null) {
logger.info(line);
}
in.close();
proc.waitFor();
return "根据自己情况返回结果";
}
}
}