收藏 分享(赏)

java多线程机制.doc

上传人:tkhy51908 文档编号:6893202 上传时间:2019-04-25 格式:DOC 页数:5 大小:57KB
下载 相关 举报
java多线程机制.doc_第1页
第1页 / 共5页
java多线程机制.doc_第2页
第2页 / 共5页
java多线程机制.doc_第3页
第3页 / 共5页
java多线程机制.doc_第4页
第4页 / 共5页
java多线程机制.doc_第5页
第5页 / 共5页
亲,该文档总共5页,全部预览完了,如果喜欢就下载吧!
资源描述

1、Java 的多进程运行模式分析编辑推荐:Java 线程和多线程资料合集一般我们在 java 中运行其它类中的方法时,无论是静态调用,还是动态调用,都是在当前的进程中执行的,也就是说,只有一个 java 虚拟机实例在运行。而有的时候,我们需要通过 java 代码启动多个java 子进程。这样做虽然占用了一些系统资源,但会使程序更加稳定,因为新启动的程序是在不同的虚拟机进程中运行的,如果有一个进程发生异常,并不影响其它的子进程。在 Java 中我们可以使用两种方法来实现这种要求。最简单的方法就是通过 Runtime 中的 exec 方法执行java classname。如果执行成功,这个方法返回一

2、个 Process 对象,如果执行失败,将抛出一个 IOException错误。下面让我们来看一个简单的例子。 / Test1.java 文件import java.io.*;public class Testpublic static void main(String args)FileOutputStream fOut = new FileOutputStream(“c:Test1.txt“);fOut.close();System.out.println(“被调用成功!“);/ Test_Exec.javapublic class Test_Execpublic static void

3、main(String args)Runtime run = Runtime.getRuntime();Process p = run.exec(“java test1“); / Test_Exec_Out.javaimport java.io.*;public class Test_Exec_Outpublic static void main(String args)Runtime run = Runtime.getRuntime();Process p = run.exec(“java test1“); BufferedInputStream in = new BufferedInput

4、Stream(p.getInputStream();BufferedReader br = new BufferedReader(new InputStreamReader(in);String s;while (s = br.readLine() != null)System.out.println(s); 从上面的代码可以看出,在 Test_Exec_Out.java 中通过按行读取子进程的输出信息,然后在Test_Exec_Out 中按每行进行输出。 上面讨论的是如何得到子进程的输出信息。那么,除了输出信息,还通过 java Test_Exec 运行程序后,发现在 C 盘多了个 Test

5、1.txt 文件,但在控制台中并未出现“被调用成功!“的输出信息。因此可以断定,Test 已经被执行成功,但因为某种原因,Test的输出信息未在 Test_Exec 的控制台中输出。这个原因也很简单,因为使用 exec 建立的是Test_Exec 的子进程,这个子进程并没有自己的控制台,因此,它并不会输出任何信息。 如果要输出子进程的输出信息,可以通过Process 中的 getInputStream 得到子进程的输出流(在子进程中输出,在父进程中就是输入) ,然后将子进程中的输出流从父进程的控制台输出。具体的实现代码如下如示:有输入信息。既然子进程没有自己的控制台,那么输入信息也得由父进程提

6、供。我们可以通过 Process 的getOutputStream 方法来为子进程提供输入信息(即由父进程向子进程输入信息,而不是由控制台输入信息)。我们可以看看如下的代码: / Test2.java 文件import java.io.*;public class Testpublic static void main(String args)BufferedReader br = new BufferedReader(new InputStreamReader(System.in);System.out.println(“由父进程输入的信息:“ + br.readLine();/ Test_

7、Exec_In.javaimport java.io.*;public class Test_Exec_Inpublic static void main(String args)Runtime run = Runtime.getRuntime();Process p = run.exec(“java test2“); BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(p.getOutputStream();bw.write(“向子进程输出信息“);bw.flush();bw.close(); / 必须得关闭流,否则无法

8、向子进程中输入信息/ System.in.read();从以上代码可以看出,Test1 得到由 Test_Exec_In 发过来的信息,并将其输出。当你不加 bw.flash()和bw.close()时,信息将无法到达子进程,也就是说子进程进入阻塞状态,但由于父进程已经退出了,因此,子进程也跟着退出了。如果要证明这一点,可以在最后加上 System.in.read(),然后通过任务管理器(在windows 下)查看 java 进程,你会发现如果加上 bw.flush()和 bw.close(),只有一个 java 进程存在,如果去掉它们,就有两个 java 进程存在。这是因为,如果将信息传给

9、Test2,在得到信息后,Test2 就退出了。在这里有一点需要说明一下,exec 的执行是异步的,并不会因为执行的某个程序阻塞而停止执行下面的代码。因此,可以在运行 test2 后,仍可以执行下面的代码。exec 方法经过了多次的重载。上面使用的只是它的一种重载。它还可以将命令和参数分开,如exec(“java.test2“)可以写成 exec(“java“, “test2“)。exec 还可以通过指定的环境变量运行不同配置的 java 虚拟机。除了使用 Runtime 的 exec 方法建立子进程外,还可以通过 ProcessBuilder 建立子进程。ProcessBuilder的使用方

10、法如下:/ Test_Exec_Out.javaimport java.io.*;public class Test_Exec_Outpublic static void main(String args)ProcessBuilder pb = new ProcessBuilder(“java“, “test1“);Process p = pb.start(); 在建立子进程上,ProcessBuilder 和 Runtime 类似,不同的 ProcessBuilder 使用 start()方法启动子进程,而 Runtime 使用 exec 方法启动子进程。得到 Process 后,它们的操作

11、就完全一样的。ProcessBuilder 和 Runtime 一样,也可设置可执行文件的环境信息、工作目录等。下面的例子描述了如何使用 ProcessBuilder 设置这些信息。ProcessBuilder pb = new ProcessBuilder(“Command“, “arg2“, “arg2“, );/ 设置环境变量Map env = pb.environment();env.put(“key1“, “value1“);env.remove(“key2“);env.put(“key2“, env.get(“key1“) + “_test“); pb.directory(“abc

12、d“); / 设置工作目录Process p = pb.start(); / 建立子进程实例变量和类变量在生成每个类的实例对象时,Java 运行时系统为每个对象的实例变量分配一块内存,然后可以通过该对象来访问这些实例的变量。不同对象的实例变量是不同的。而对于类变量来说,在生成类的第一个实例对象时,Java 运行时系统对这个对象的每个类变量分配一块内存,以后再生成该类的实例对象时,这些实例对象将共享同一个类变量,每个实例对象对类变量的改变都会直接影响到其他实例对象。类变量可以通过类名直接访问,也可以通过实例对象来访问,两种方法的结果是相同的。实例方法可以对当前对象的实例变量进行操作,也可以对类变

13、量进行操作,但类方法不能访问实例变量。实例方法必须由实例对象来调用,而类方法除了可由实例对象调用外,还可以由类名直接调用。另外,在类方法中不能使用 this 或 super。关于类方法的使用,有如下一些限制: (1) 在类方法中不能引用对象变量。 (2) 在类方法中不能使用 super、this 关键字。 (3) 类方法不能调用类中的对象方法。 如果违反这些限制,你的程序就会导致编译错误。 与类方法相比,实例方法几乎没有什么限制: (1) 实例方法可以引用对象变量(这是显然的) ,也可以引用类变量。 (2) 实例方法中可以使用super、this 关键字。 (3) 实例方法中可以调用类方法。

14、下面是关于实例变量的例子 /instVar.javaclass koAint a;public void display()System.out.print(“ a=“+a);public class instVarpublic static void main(String args)koA a1=new koA(); a1.a=10; /a1 是一个实例对象koA a2=new koA(); a2.a=20; / a2 是另一个实例对象a1.display();a2.display();运行结果为 a=10 a=20 下面是类变量的例子/ classVar.javaclass koBsta

15、tic int a;public void display()System.out.print(“ a=“+a);public class classVarpublic static void main(String args)koB a1=new koB(); a1.a=10; /a1 是一个实例对象koB a2=new koB(); a2.a=20; /a2 是另一个实例对象koB.a=50; /类方法直接访问类变量a1.display(); a2.display(); 运行结果为:a=50 a=50class add static int addem(int op1,int op2) r

16、eturn op1+op2; public class xxf public static void main(String args) System.out.println(“addem(2,2)=“+add.addem(2,2); /直接用类名作为对象调用类方法 注: 也可按通常的方法,即先创建对象,再调用方法,不过,这时 static 就无任何意义了。再说说构造器方法,它是用来初始化对象中的数据的一种方法,创建很容易,只需在类中加上一个与这个类同名的方法,不需要在前面加任何访问说明符或者返回类型,另外,构造器也一样可以向方法一样传递参数. class data private Strin

17、g data1;/事先声明 data(String s) data1=s; /*通过接收数据来初始化变量.( 注:不能在构造器内 声明变量,事先在外就要声明.)*/ public String getdata() 静态变量也称作类变量,由 static 修饰,如:static int ss; ss 就是静态变量,它只能通过类来访问。实例变量没有 static 修饰符,它只能通过实例对象来访问。同一类的不同的实例对象有自己的实例变量,但是它们共享 同一个静态变量。当一个实例对象修改了它的实例变量时,不会影响其他的实例对象。如果一个实例对象修改了静态变量,则会影响其他的对象实例。 .实例方法,类方

18、法,构造器方法 我们通常所说的方法系指实例方法,就像 c 语言中的函数一样,其具体方法我就不用说了,在这里我主要是用它来区分类方法和构造器方法.类方法与实例方法最大的区别是:在形式上类方法多一个 static,在用法上, 不必创建对象就可直接调用类方法(而实例方法却一定要先创建对象,再通过对象调用)。return data1; public class xxf public static void main(String args) System.out.println(new data(“I love you“).getdata();/*通过传递参数调用构造器新建一 个对象,再通过对象调用方

19、法得到数据*/ .实例变量与类变量 可以通过两种方法在类中存储数据作为实例变量和类变量.实例变量是特定于对象的,如果你有两个对象(即一个类的两个实例),每一个对象中的实例变量独立于另一个对象中的实例变量的 ;另一方面,两个对象的类变量均指向相同的数据,并因此面保存相同的值,换句话说,类变量被类中的所有对象共享.差点忘了,它们在形式上的区别,类变量在声明时比实例变量多一个 static. class data public int intdata=0;/显然,intdata 在这儿是实例变量 public class exam public static void main(String arg

20、s) data a,b; a=new data(); b=new data(); a.intdata=1; System.out.println(“b.indata=“+b.intdata); 运行结果: b.intdata=0 结果分析: 可以看出,a.intdata 的值虽然变了,但并没有影响b.intdata.但是如果在 data 类中声明 intdata 时,在其前面加上 static就变成类变量了(即:public static int intdata=0;),则此时运行结果会变为: b.intdata=1 (这次 a.intdata 值的改变可把 b.intdata 影响了,事实上,对象 a 和 b 的类变量均指向相同的数据,所有值一样,这就是类变量的作用。 )现有关系模式 R(A,B,C,D,E) ,其中:AB 组合为码。R 上存在的函数依赖有(AB)E ,BC,CD 该关系模式满足 2NF 吗?为什么? 如果将关系模式 R 分解为:R1(A,B,E)和R2(B,C ,D),指出关系模式 R2 的码,并说明该关系模式最高满足第几范式? 将关系模式 R 分解到 BCNF。

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 企业管理 > 管理学资料

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报