发现就是个坑,Java的多进程无论是ProcessBuild还是Runtime,都是cmd启动另一个进程,虽然父进程可以从子进程拿到IO流,但是又有什么用呢?照样没法实现同步互斥。Java进程间通信没有管道,没有共享内存,难道要我用共享文件,可是共享文件本身就存在同步互斥问题。于是只好放弃。
以下的代码并没有解决生产者消费者问题,只是我用FileLock的探索,加上该死的IO流。
importjava.io.BufferedReader; importjava.io.IOException; importjava.io.InputStream; importjava.io.InputStreamReader; public class ProcessLauncher { public static void main(String[] args) { ProcessLauncherlauncher = new ProcessLauncher(); int p = 0; int c = 0; if (args.length != 2) { System.out.println("please input /"ConditionLauncher [p] [c]/""); return; } try { p = Integer.parseInt(args[0]); c = Integer.parseInt(args[1]); } catch (NumberFormatException e) { e.printStackTrace(); } try { for (int i = 0; i < p; i++) { ProcessBuilderproducerBuilder = new ProcessBuilder(); producerBuilder.command("java", "Producer", i + ""); producerBuilder.redirectErrorStream(); Processprocess = producerBuilder.start(); launcher.newOutputThread(process.getInputStream()).start(); } for (int i = 0; i < c; i++) { ProcessBuilderconsumerBuilder = new ProcessBuilder(); consumerBuilder.command("java", "Consumer", i + ""); consumerBuilder.redirectErrorStream(); Processprocess = consumerBuilder.start(); launcher.newOutputThread(process.getInputStream()).start(); } } catch (IOException e) { e.printStackTrace(); } } // 用来打印子进程的输入流 class OutputThread extends Thread { private InputStreaminput; public OutputThread(InputStreaminput) { this.input = input; } @Override public void run() { try { BufferedReaderreader = new BufferedReader(new InputStreamReader(input)); String tempString = null; while ((tempString = reader.readLine()) != null) { System.out.println(tempString); } } catch (IOException e) { e.printStackTrace(); } } } }
消费者
importjava.io.BufferedWriter; importjava.io.File; importjava.io.FileOutputStream; importjava.io.IOException; importjava.io.OutputStreamWriter; importjava.nio.channels.FileLock; public class Consumer { public static void main(String[] args) { String processName = "Consumer " + args[0]; FileLocklock = null; // 文件锁 BufferedWriterout = null; while (true) { try { Filefile = new File(Util.PATH); if (!file.exists()) file.createNewFile(); int num = Integer.parseInt(Util.readFile()); try { Thread.sleep(500); } catch (InterruptedExceptione1) { // TODO Auto-generated catch block e1.printStackTrace(); } System.out.println(processName + ":" + num); if (num == 0) continue; try { if (!file.exists()) file.createNewFile(); FileOutputStreamoutput = new FileOutputStream(file); OutputStreamWriterwriter = new OutputStreamWriter(output); lock = output.getChannel().lock(); out = new BufferedWriter(writer); System.out.println(processName + ": " + num + " -> " + (num - 1)); out.write((num - 1) + ""); out.flush(); } catch (IOException e) { e.printStackTrace(); } finally { if (lock != null) { lock.release(); } if (out != null) { out.close(); } } } catch (IOException e) { e.printStackTrace(); } } } }
生产者
importjava.io.BufferedWriter; importjava.io.File; importjava.io.FileOutputStream; importjava.io.IOException; importjava.io.OutputStreamWriter; importjava.nio.channels.FileLock; public class Producer { public static void main(String[] args) { String processName = "Producer " + args[0]; FileLocklock = null; // 文件锁 BufferedWriterout = null; while (true) { try { Filefile = new File(Util.PATH); if (!file.exists()) file.createNewFile(); int num = Integer.parseInt(Util.readFile()); try { Thread.sleep(500); } catch (InterruptedExceptione1) { // TODO Auto-generated catch block e1.printStackTrace(); } System.out.println(processName + ":" + num); if (num == Util.MAX_SIZE) continue; try { if (!file.exists()) file.createNewFile(); FileOutputStreamoutput = new FileOutputStream(file); OutputStreamWriterwriter = new OutputStreamWriter(output); lock = output.getChannel().lock(); out = new BufferedWriter(writer); System.out.println(processName + ": " + num + " -> " + (num + 1)); out.write((num + 1) + ""); out.flush(); } catch (IOException e) { e.printStackTrace(); } finally { if (lock != null) { lock.release(); } if (out != null) { out.close(); } } } catch (IOException e) { e.printStackTrace(); } } } }
发现实在搞不定以后,我转而去用Python实现,还是Python大法好。