「java创建进程」java创建程序
今天给各位分享java创建进程的知识,其中也会对java创建程序进行解释,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!
本文目录一览:
- 1、JAVA 创建多进程问题
- 2、新建.java文件,右击用Vim编辑,却弹出错误,上写---创建进程失败:请检查Gvim是否在路径中,请问咋解决
- 3、Java中如何创建进程
- 4、从Java类到对象的创建过程都做了些啥
- 5、操作系统 思考题 系统是怎样创建进程的
- 6、java 怎么创建一个新的进程
JAVA 创建多进程问题
你的Test_Exec类中,Process p = run.exec("java test1");这句是执行dos命令的,而java test1如果有这个class文件的话确实可以执行,但是问题是,你要放对地方这个test1.class文件放在C盘根目录下是不行的,你看看你dos窗口的现实的路径就知道了,而且还不考虑你的test1类有包名的情况
新建.java文件,右击用Vim编辑,却弹出错误,上写---创建进程失败:请检查Gvim是否在路径中,请问咋解决
# 修改注册表法
打开注册表编辑器regedit.exe;
搜索“gvim.exe”,找到没有对全路径加双引号的值,用双引号(英文双引号,不是中文双引号)从盘符到exe后缀都包起来。
从我自己检查的情况看修改了以下4处:
```
计算机\HKEY_CLASSES_ROOT\TypeLib\{0F0BFAE0-4C90-11D1-82D7-0004AC368519}\1.1\0\win32
计算机\HKEY_CLASSES_ROOT\WOW6432Node\CLSID\{0F0BFAE1-4C90-11D1-82D7-0004AC368519}\LocalServer32
计算机\HKEY_LOCAL_MACHINE\SOFTWARE\Vim\Gvim
计算机\HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Vim\Gvim
```
# 改路径重装
从上一种方法可推测大概是路径中的空格导致的问题。
将软件卸载;重装时选择安装路径为没有空格和中文字符的,即路径是全英文字母的目录。
Java中如何创建进程
new Thread(){
public void run(){
for(int i=0; i100; i++){
System.out.println(i);
}
}
}.start();
从Java类到对象的创建过程都做了些啥
Java程序执行时,第一步系统创建虚拟机进程,然后虚拟器用类加载器Class Loader加载java程序类文件到方法区。
存放加载过的类信息、常量、静态变量、及jit编译后的代码(类方法)等数据的内存区域。它是线程共享的。
方法区存放的信息包括:类的基本信息、运行时常量池、变量字段信息、方法信息等。
操作系统 思考题 系统是怎样创建进程的
在编写Java程序时,有时候需要在Java程序中执行另外一个程序。1、启动程序Java提供了两种方法用来启动其它程序:(1)使用Runtime的exec()方法(2)使用ProcessBuilder的start()方法不管在哪种操作系统下,程序具有基本类似的一些属性。一个程序启动后就程序操作系统的一个进程,进程在执行的时候有自己的环境变量、有自己的工作目录。Runtime和ProcessBuilder提供了不同的方式来启动程序,设置启动参数、环境变量和工作目录。能够在Java中执行的外部程序,必须是一个实际存在的可执行文件,对于shell下的内嵌命令是不能直接执行的。采用Runtime的exec执行程序时,首先要使用Runtime的静态方法得到一个Runtime,然后调用Runtime的exec方法。可以将要执行的外部程序和启动参数、环境变量、工作目录作为参数传递给exec方法,该方法执行后返回一个Process代表所执行的程序。Runtime有六个exec方法,其中两个的定义为:publicProcessexec(String[]cmdarray,String[]envp,Filedir)publicProcessexec(Stringcommand,String[]envp,Filedir)cmdarray和command为要执行的命令,可以将命令和参数作为一个字符串command传递给exec()方法,也可以将命令和参数一个一个的方在数组cmdarray里传递给exec()方法。envp为环境变量,以name=value的形式放在数组中。dir为工作目录。可以不要dir参数,或者不要envp和dir参数,这样就多出了其它4个exec()方法。如果没有dir参数或者为null,那么新启动的进程就继承当前java进程的工作目录。如果没有envp参数或者为null,那么新启动的进程就继承当前java进程的环境变量。也可以使用ProcessBuilder类启动一个新的程序,该类是后来添加到JDK中的,而且被推荐使用。通过构造函数设置要执行的命令以及参数,或者也可以通过command()方法获取命令信息后在进行设置。通过directory(Filedirectory)方法设置工作目录,通过environment()获取环境变量信息来修改环境变量。在使用ProcessBuilder构造函数创建一个新实例,设置环境变量、工作目录后,可以通过start()方法来启动新程序,与Runtime的exec()方法一样,该方法返回一个Process对象代表启动的程序。ProcessBuilder与Runtime.exec()方法的不同在于ProcessBuilder提供了redirectErrorStream(booleanredirectErrorStream)方法,该方法用来将进程的错误输出重定向到标准输出里。即可以将错误输出都将与标准输出合并。2、Process不管通过那种方法启动进程后,都会返回一个Process类的实例代表启动的进程,该实例可用来控制进程并获得相关信息。Process类提供了执行从进程输入、执行输出到进程、等待进程完成、检查进程的退出状态以及销毁(杀掉)进程的方法:(1)voiddestroy()杀掉子进程。一般情况下,该方法并不能杀掉已经启动的进程,不用为好。(2)intexitValue()返回子进程的出口值。只有启动的进程执行完成、或者由于异常退出后,exitValue()方法才会有正常的返回值,否则抛出异常。(3)InputStreamgetErrorStream()获取子进程的错误流。如果错误输出被重定向,则不能从该流中读取错误输出。(4)InputStreamgetInputStream()获取子进程的输入流。可以从该流中读取进程的标准输出。(5)OutputStreamgetOutputStream()获取子进程的输出流。写入到该流中的数据作为进程的标准输入。(6)intwaitFor()导致当前线程等待,如有必要,一直要等到由该Process对象表示的进程已经终止。通过该类提供的方法,可以实现与启动的进程之间通信,达到交互的目的。3、从标准输出和错误输出流读取信息从启动其他程序的Java进程看,已启动的其他程序输出就是一个普通的输入流,可以通过getInputStream()和getErrorStream来获取。对于一般输出文本的进程来说,可以将InputStream封装成BufferedReader,然后就可以一行一行的对进程的标准输出进行处理。4、举例(1)Runtime.exec()importjava.io.BufferedReader;importjava.io.File;importjava.io.InputStreamReader;publicclassTest1{publicstaticvoidmain(String[]args){try{Processp=null;Stringline=null;BufferedReaderstdout=null;//listthefilesanddirectorysunderC:\p=Runtime.getRuntime().exec("CMD.exe/Cdir",null,newFile("C:\\"));stdout=newBufferedReader(newInputStreamReader(p.getInputStream()));while((line=stdout.readLine())!=null){System.out.println(line);}stdout.close();//echothevalueofNAMEp=Runtime.getRuntime().exec("CMD.exe/Cecho%NAME%",newString[]{"NAME=TEST"});stdout=newBufferedReader(newInputStreamReader(p.getInputStream()));while((line=stdout.readLine())!=null){System.out.println(line);}stdout.close();}catch(Exceptione){e.printStackTrace();}}(2)ProcessBuilderimportjava.io.BufferedReader;importjava.io.File;importjava.io.InputStreamReader;importjava.util.ArrayList;importjava.util.List;publicclassTest2{publicstaticvoidmain(String[]args){try{Listlist=newArrayList();ProcessBuilderpb=null;Processp=null;Stringline=null;BufferedReaderstdout=null;//listthefilesanddirectorysunderC:\list.add("CMD.EXE");list.add("/C");list.add("dir");pb=newProcessBuilder(list);pb.directory(newFile("C:\\"));p=pb.start();stdout=newBufferedReader(newInputStreamReader(p.getInputStream()));while((line=stdout.readLine())!=null){System.out.println(line);}stdout.close();//echothevalueofNAMEpb=newProcessBuilder();mand(newString[]{"CMD.exe","/C","echo%NAME%"});pb.environment().put("NAME","TEST");p=pb.start();stdout=newBufferedReader(newInputStreamReader(p.getInputStream()));while((line=stdout.readLine())!=null){System.out.println(line);}stdout.close();}catch(Exceptione){e.printStackTrace();}}}5、获取进程的返回值通常,一个程序/进程在执行结束后会向操作系统返回一个整数值,0一般代表执行成功,非0表示执行出现问题。有两种方式可以用来获取进程的返回值。一是利用waitFor(),该方法是阻塞的,执导进程执行完成后再返回。该方法返回一个代表进程返回值的整数值。另一个方法是调用exitValue()方法,该方法是非阻塞的,调用立即返回。但是如果进程没有执行完成,则抛出异常。6、阻塞的问题由Process代表的进程在某些平台上有时候并不能很好的工作,特别是在对代表进程的标准输入流、输出流和错误输出进行操作时,如果使用不慎,有可能导致进程阻塞,甚至死锁。如果将以上事例中的从标准输出重读取信息的语句修改为从错误输出流中读取:stdout=newBufferedReader(newInputStreamReader(p.getErrorStream()));那么程序将发生阻塞,不能执行完成,而是hang在那里。当进程启动后,就会打开标准输出流和错误输出流准备输出,当进程结束时,就会关闭他们。在以上例子中,错误输出流没有数据要输出,标准输出流中有数据输出。由于标准输出流中的数据没有被读取,进程就不会结束,错误输出流也就不会被关闭,因此在调用readLine()方法时,整个程序就会被阻塞。为了解决这个问题,可以根据输出的实际先后,先读取标准输出流,然后读取错误输出流。但是,很多时候不能很明确的知道输出的先后,特别是要操作标准输入的时候,情况就会更为复杂。这时候可以采用线程来对标准输出、错误输出和标准输入进行分别处理,根据他们之间在业务逻辑上的关系决定读取那个流或者写入数据。针对标准输出流和错误输出流所造成的问题,可以使用ProcessBuilder的redirectErrorStream()方法将他们合二为一,这时候只要读取标准输出的数据就可以了。当在程序中使用Process的waitFor()方法时,特别是在读取之前调用waitFor()方法时,也有可能造成阻塞。可以用线程的方法来解决这个问题,也可以在读取数据后,调用waitFor()方法等待程序结束。总之,解决阻塞的方法应该有两种:(1)使用ProcessBuilder类,利用redirectErrorStream方法将标准输出流和错误输出流合二为一,在用start()方法启动进程后,先从标准输出中读取数据,然后调用waitFor()方法等待进程结束。如:importjava.io.BufferedReader;importjava.io.File;importjava.io.InputStreamReader;importjava.util.ArrayList;importjava.util.List;publicclassTest3{publicstaticvoidmain(String[]args){try{Listlist=newArrayList();ProcessBuilderpb=null;Processp=null;Stringline=null;BufferedReaderstdout=null;//listthefilesanddirectorysunderC:\list.add("CMD.EXE");list.add("/C");list.add("dir");pb=newProcessBuilder(list);pb.directory(newFile("C:\\"));//mergetheerroroutputwiththestandardoutputpb.redirectErrorStream(true);p=pb.start();//readthestandardoutputstdout=newBufferedReader(newInputStreamReader(p.getInputStream()));while((line=stdout.readLine())!=null){System.out.println(line);}intret=p.waitFor();System.out.println("thereturncodeis"+ret);stdout.close();}catch(Exceptione){e.printStackTrace();}}}(2)使用线程importjava.util.*;importjava.io.*;classStreamWatchextendsThread{InputStreamis;Stringtype;Listoutput=newArrayList();booleandebug=false;StreamWatch(InputStreamis,Stringtype){this(is,type,false);}StreamWatch(InputStreamis,Stringtype,booleandebug){this.is=is;this.type=type;this.debug=debug;}publicvoidrun(){try{PrintWriterpw=null;InputStreamReaderisr=newInputStreamReader(is);BufferedReaderbr=newBufferedReader(isr);Stringline=null;while((line=br.readLine())!=null){output.add(line);if(debug)System.out.println(type+""+line);}if(pw!=null)pw.flush();}catch(IOExceptionioe){ioe.printStackTrace();}}publicListgetOutput(){returnoutput;}}publicclassTest5{publicstaticvoidmain(Stringargs[]){try{Listlist=newArrayList();ProcessBuilderpb=null;Processp=null;//listthefilesanddirectorysunderC:\list.add("CMD.EXE");list.add("/C");list.add("dir");pb=newProcessBuilder(list);pb.directory(newFile("C:\\"));p=pb.start();//processerrorandoutputmessageStreamWatcherrorWatch=newStreamWatch(p.getErrorStream(),"ERROR");StreamWatchoutputWatch=newStreamWatch(p.getInputStream(),"OUTPUT");//starttowatcherrorWatch.start();outputWatch.start();//waitforexitintexitVal=p.waitFor();//printthecontentfromERRORandOUTPUTSystem.out.println("ERROR:"+errorWatch.getOutput());System.out.println("OUTPUT:"+outputWatch.getOutput());System.out.println("thereturncodeis"+exitVal);}catch(Throwablet){t.printStackTrace();}}}7、在Java中执行Java程序执行一个Java程序的关键在于:(1)知道JAVA虚拟机的位置,即java.exe或者java的路径(2)知道要执行的java程序的位置(3)知道该程序所依赖的其他类的位置举一个例子,一目了然。(1)待执行的Java类publicclassMyTest{publicstaticvoidmain(String[]args){System.out.println("OUTPUTone");System.out.println("OUTPUTtwo");System.err.println("ERROR1");System.err.println("ERROR2");for(inti=0;i"+line);}if(pw!=null)pw.flush();}catch(IOExceptionioe){ioe.printStackTrace();}}publicListgetOutput(){returnoutput;}}publicclassTest6{publicstaticvoidmain(Stringargs[]){try{Listlist=newArrayList();ProcessBuilderpb=null;Processp=null;Stringjava=System.getProperty("java.home")+File.separator+"bin"+File.separator+"java";Stringclasspath=System.getProperty("java.class.path");//listthefilesanddirectorysunderC:\list.add(java);list.add("-classpath");list.add(classpath);list.add(MyTest.class.getName());list.add("hello");list.add("world");list.add("goodbetterbest");pb=newProcessBuilder(list);p=pb.start();System.out.println(mand());//processerrorandoutputmessageStreamWatcherrorWatch=newStreamWatch(p.getErrorStream(),"ERROR");StreamWatchoutputWatch=newStreamWatch(p.getInputStream(),"OUTPUT");//starttowatcherrorWatch.start();outputWatch.start();//waitforexitintexitVal=p.waitFor();//printthecontentfromERRORandOUTPUTSystem.out.println("ERROR:"+errorWatch.getOutput());System.out.println("OUTPUT:"+outputWatch.getOutput());System.out.println("thereturncodeis"+exitVal);}catch(Throwablet){t.printStackTrace();}}}
java 怎么创建一个新的进程
不能创建进程,只能创建线程
在Java中,类仅支持单继承,也就是说,当定义一个新的类的时候,它只能扩展一个外部类.这样,如果创建自定义线程类的时候是通过扩展 Thread类的方法来实现的,那么这个自定义类就不能再去扩展其他的类,也就无法实现更加复杂的功能。因此,如果自定义类必须扩展其他的类,那么就可以使用实现Runnable接口的方法来定义该类为线程类,这样就可以避免Java单继承所带来的局限性。
还有一点最重要的就是使用实现Runnable接口的方式创建的线程可以处理同一资源,从而实现资源的共享.
(1)通过扩展Thread类来创建多线程
假设一个影院有三个售票口,分别用于向儿童、成人和老人售票。影院为每个窗口放有100张电影票,分别是儿童票、成人票和老人票。三个窗口需要同时卖票,而现在只有一个售票员,这个售票员就相当于一个CPU,三个窗口就相当于三个线程。通过程序来看一看是如何创建这三个线程的。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
span style="font-size: 16px;"public class MutliThreadDemo {
public static void main(String [] args){
MutliThread m1=new MutliThread("Window 1");
MutliThread m2=new MutliThread("Window 2");
MutliThread m3=new MutliThread("Window 3");
m1.start();
m2.start();
m3.start();
}
}
class MutliThread extends Thread{
private int ticket=100;//每个线程都拥有100张票
MutliThread(String name){
super(name);//调用父类带参数的构造方法
}
public void run(){
while(ticket0){
System.out.println(ticket--+" is saled by "+Thread.currentThread().getName());
}
}
}
/span
程序中定义一个线程类,它扩展了Thread类。利用扩展的线程类在MutliThreadDemo类的主方法中创建了三个线程对象,并通过start()方法分别将它们启动。
从结果可以看到,每个线程分别对应100张电影票,之间并无任何关系,这就说明每个线程之间是平等的,没有优先级关系,因此都有机会得到CPU的处理。但是结果显示这三个线程并不是依次交替执行,而是在三个线程同时被执行的情况下,有的线程被分配时间片的机会多,票被提前卖完,而有的线程被分配时间片的机会比较少,票迟一些卖完。
可见,利用扩展Thread类创建的多个线程,虽然执行的是相同的代码,但彼此相互独立,且各自拥有自己的资源,互不干扰。
(2)通过实现Runnable接口来创建多线程
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
span style="font-size: 16px;"public class MutliThreadDemo2 {
public static void main(String [] args){
MutliThread m1=new MutliThread("Window 1");
MutliThread m2=new MutliThread("Window 2");
MutliThread m3=new MutliThread("Window 3");
Thread t1=new Thread(m1);
Thread t2=new Thread(m2);
Thread t3=new Thread(m3);
t1.start();
t2.start();
t3.start();
}
}
class MutliThread implements Runnable{
private int ticket=100;//每个线程都拥有100张票
private String name;
MutliThread(String name){
this.name=name;
}
public void run(){
while(ticket0){
System.out.println(ticket--+" is saled by "+name);
}
}
}
/span
由于这三个线程也是彼此独立,各自拥有自己的资源,即100张电影票,因此程序输出的结果和(1)结果大同小异。均是各自线程对自己的100张票进行单独的处理,互不影响。
可见,只要现实的情况要求保证新建线程彼此相互独立,各自拥有资源,且互不干扰,采用哪个方式来创建多线程都是可以的。因为这两种方式创建的多线程程序能够实现相同的功能。
由于这三个线程也是彼此独立,各自拥有自己的资源,即100张电影票,因此程序输出的结果和例4.2.1的结果大同小异。均是各自线程对自己的100张票进行单独的处理,互不影响。
可见,只要现实的情况要求保证新建线程彼此相互独立,各自拥有资源,且互不干扰,采用哪个方式来创建多线程都是可以的。因为这两种方式创建的多线程程序能够实现相同的功能。
(3)通过实现Runnable接口来实现线程间的资源共享
现实中也存在这样的情况,比如模拟一个火车站的售票系统,假如当日从A地发往B地的火车票只有100张,且允许所有窗口卖这100张票,那么每一个窗口也相当于一个线程,但是这时和前面的例子不同之处就在于所有线程处理的资源是同一个资源,即100张车票。如果还用前面的方式来创建线程显然是无法实现的,这种情况该怎样处理呢?看下面这个程序,程序代码如下所示:
+ View Code
结果正如前面分析的那样,程序在内存中仅创建了一个资源,而新建的三个线程都是基于访问这同一资源的,并且由于每个线程上所运行的是相同的代码,因此它们执行的功能也是相同的。
可见,如果现实问题中要求必须创建多个线程来执行同一任务,而且这多个线程之间还将共享同一个资源,那么就可以使用实现Runnable接口的方式来创建多线程程序。而这一功能通过扩展Thread类是无法实现的,读者想想看,为什么?
实现Runnable接口相对于扩展Thread类来说,具有无可比拟的优势。这种方式不仅有利于程序的健壮性,使代码能够被多个线程共享,而且代码和数据资源相对独立,从而特别适合多个具有相同代码的线程去处理同一资源的情况。这样一来,线程、代码和数据资源三者有效分离,很好地体现了面向对象程序设计的思想。因此,几乎所有的多线程程序都是通过实现Runnable接口的方式来完成的。
关于java创建进程和java创建程序的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。
发布于:2022-12-19,除非注明,否则均为
原创文章,转载请注明出处。