欢迎访问悦橙教程(wld5.com),关注java教程。悦橙教程  java问答|  每日更新
页面导航 : > > 文章正文

Java线程和进程,Java线程进程

来源: javaer 分享于  点击 32199 次 点评:234

Java线程和进程,Java线程进程


Java应用程序的入口就是main方法()

启动一个Java应用程序,就是要运用它的main方法,这时候就启动了一个Java虚拟机------在Windows下查看任务管理器,就会发现多出了一个javaw.exe的进程,这个就是java虚拟机!而main()方法其实是Java虚拟机这个进程的一个主线程(默认至少还有一个垃圾回收器的守护线程,所以运行一个java应用程序,启动了一个java进程的同时,至少又启动了2个java线程)!main方法执行结束,java虚拟机自动就销毁了,进程就结束啦!

所以,我们同时运行了2个java类的main()方法,这时候操作系统会启动2个java进程。

但是,Java进程间是不能直接通信的

进程,是针对于操作系统而言的
线程,是java中一个重要的类,主要用来多个方法一起执行

进程,是针对于操作系统而言的,重量级,而且进程堆栈都是独立的,
线程是进程内部的单一的顺序流,堆共享,栈独立

========================================

原址: http://blog.sina.com.cn/s/blog_638d75a20101jw39.html


======================================================================================

从计算机操作系统的发展来看,经历了这样的两个阶段:

单进程处理:最传统的DOS 系统中只要有病毒出现,则立刻有反映,因为在DOS 系统中属于进程处理,即:在同一个时间段上只能有一个程序在执行

多进程处理:windows操作系统是一个多进程,例如,假设在windows 中出现病毒了,则系统照样可以使用



那么对于资源来讲,所有IO设置、CUP等等都只有一个,那么对于多进程的处理来讲,在同一个时间段上会有多个程序运行,但是在同一个时间点上只能有一个程序运行


线程是在进程基础上的进一步划分,举个不恰当的例子来说:word 中的拼写检查,是在word整个程序运行中运行的。

所以,如果进程,则线程就消失,而如果线程消失的话,则进程依然会执行,未必会消失。


Java 本身是属于多线程的操作语言,所以提供了线程的处理机制。


线程实现的两种方式

在Java 中可以有两种方式实现多线程操作,一种是继承Tread类,另外一种是实现Runnable 接口


Thread 类


Thread 类是在java.lang 包中定义

一个类只要继承了Thread类,同时覆写了本类中的run()方法,则就可以实现多线程的操作了


[java] view plaincopyprint?
  1. package org.threaddemo;  
  2.   
  3. public class MyThread extends Thread{  
  4.     private String name; //定义name 属性  
  5.       
  6.     public MyThread(String name){  
  7.         this.name = name;  
  8.     }  
  9.       
  10.     public void run(){ //覆写run()方法  
  11.         for (int i=0;i<50;i++){ // 表示循环50次  
  12.             System.out.println("Thread 测试"+this.name+" i:"+i);  
  13.         }  
  14.     }  
  15.   
  16. }  


以上的类已经完成了多线程的操作类,那么下面就启动线程


[java] view plaincopyprint?
  1. package org.threaddemo;  
  2.   
  3. public class ThreadDemo02 {  
  4.   
  5.     /** 
  6.      * @param args 
  7.      */  
  8.     public static void main(String[] args) {  
  9.         // TODO Auto-generated method stub  
  10.           
  11.         MyThread th1 = new MyThread("A类");  
  12.         MyThread th2 = new MyThread("B类");  
  13.           
  14.         th1.run();  
  15.         th2.run();  
  16.     }  
  17.   
  18. }  


但是,此时的执行可以发现非常的有规律,先执行完第一个对象,再执行第二个对象,也就是说并没有实现交互的运行

从JDK的文档中可以发现,一旦调用strat()方法,则会通过JVM找到run()方法


public void start()


[java] view plaincopyprint?
  1. package org.threaddemo;  
  2.   
  3. public class ThreadDemo02 {  
  4.   
  5.     /** 
  6.      * @param args 
  7.      */  
  8.     public static void main(String[] args) {  
  9.         // TODO Auto-generated method stub  
  10.           
  11.         MyThread th1 = new MyThread("A类");  
  12.         MyThread th2 = new MyThread("B类");  
  13.           
  14.         th1.start();  
  15.         th2.start();  
  16.     }  
  17.   
  18. }  


此时,程序已经可以正常的进行交互式的运行了。

但是,需要思考的是,为什么非要使用start()方法启动多线程呢?

在JDK 的安装路径下,src.zip是全部的java 源程序,通过此代码找到 Thread 类中的 start()方法的定义:


[java] view plaincopyprint?
  1. public synchronized void start(){ //定义的start()方法  
  2.     if (started) //判断线程是否已经启动  
  3.         throw new IllegalThreadStateException();  
  4.     started = true;//如果没有启动则修改状态  
  5.     start0();//调用start0()方法  
  6. }  
  7.   
  8. private native void start0(); //使用 natvie 关键字声明的方法,没有方法体  


操作系统有很多种,Windows、Linux、UNIX,既然多线程操作中要进行CPU资源的强占,也就是说要等待CPU调度,那么这些调度的操作是由各个操作系统的低层实现的,所以在java程序中根中就没法实现,那么此时Java的设计者定义了native 关键字,使用此关键字表示可以调用操作系统的低层函数,那么这样的技术又称为JNI技术(Java Native Interface)

而且,此方法在执行的时候将调用run()方法完成,由系统默认调用的

但是,第一种操作中有一个最大的限制,一个类只能继承一个父类


Runnable 接口


在实际的开发中一个多线程的操作类很少去使用Thread 类完成,而是通过Runnable 接口完成。

观察Runnable 接口的定义:


[java] view plaincopyprint?
  1. public interface Runnable{  
  2.     public void run();  
  3. }  

所以,一个类只要实现了此接口,并覆写 run()方法


[java] view plaincopyprint?
  1. package org.threaddemo;  
  2.   
  3. public class RunnableDemo implements Runnable{ //实现Runnable 接口  
  4.     private String name; // 定义name 属性  
  5.       
  6.     public RunnableDemo(String name){  
  7.         this.name = name;  
  8.     }  
  9.       
  10.     public void run(){ //覆写run()方法  
  11.         for (int i=0;i<50;i++){ //表示循环10次  
  12.             System.out.println("Thread 测试"+this.name+" i:"+i);  
  13.         }  
  14.     }  
  15.   
  16. }  

完成之后,下面继续启动多线程

但在现在使用Runnable 定义的子类中并没有start()方法,而只有Thread类中才有

在Thread 类中存在以下的一个构造方法:


public Thread(Runnable target)


此构造方法接收Runnable 的子类实例。也就是说现在可以通过Thread 类中启动 Runnable 实现的多线程


[java] view plaincopyprint?
  1. package org.threaddemo;  
  2.   
  3. public class ThreadDemo02 {  
  4.   
  5.     /** 
  6.      * @param args 
  7.      */  
  8.     public static void main(String[] args) {  
  9.         // TODO Auto-generated method stub  
  10.           
  11.         MyThread th1 = new MyThread("A类");  
  12.         MyThread th2 = new MyThread("B类");  
  13.           
  14.         new Thread(th1).start(); //调用线程体  
  15.         new Thread(th2).start(); //调用线程体  
  16.     }  
  17.   
  18. }  

以上的操作代码也属于交替的运行,所以此时程序也同样实现了多线程的操作


两种实现方式的区别及联系


在程序的开发中只要是多线程则肯定永远以实现Runnable 接口为正统操作,因为实现Runnable 接口相比继承 Thread 类有如下的好处

避免单继承的局限,一个类可以同时实现多个接口

适合于资源的共享


以卖票的程序为例


[java] view plaincopyprint?
  1. public class TicketsDemo extends Thread { //继承 Thread  
  2.     private int TiceketsDemo = 5// 一共才5张票  
  3.       
  4.     public void run(){ //覆写 run()方法  
  5.         for (int i=0;i<50;i++){ //表示循环50次  
  6.             if (this.TiceketsDemo>0){   
  7.                 System.out.println("出票:"+this.TiceketsDemo--);  
  8.             }  
  9.         }  
  10.     }  
  11.   
  12. }  

下面建立三个线程对象,同时卖票


[java] view plaincopyprint?
  1. package org.threaddemo;  
  2.   
  3. public class ThreadDemo03 {  
  4.   
  5.     /** 
  6.      * @param args 
  7.      */  
  8.     public static void main(String[] args) {  
  9.         // TODO Auto-generated method stub  
  10.         TicketsDemo tic1 = new TicketsDemo(); //一个线程  
  11.         TicketsDemo tic2 = new TicketsDemo(); //一个线程  
  12.         TicketsDemo tic3 = new TicketsDemo(); //一个线程  
  13.           
  14.         tic1.start(); //开始卖票  
  15.         tic2.start(); //开始卖票  
  16.         tic3.start(); //开始卖票  
  17.     }  
  18.   
  19. }  

发现现在一共买了15张票,但是实际上只有5张票。所以证明每一个线程都买自己的票,没有达到资源共享的目的


那么,如果现在实现的是Runnable 接口的话,则就可以实现资源的共享:


[java] view plaincopyprint?
  1. package org.threaddemo;  
  2.   
  3. public class ThreadDemo03 {  
  4.   
  5.     /** 
  6.      * @param args 
  7.      */  
  8.     public static void main(String[] args) {  
  9.         // TODO Auto-generated method stub  
  10.         TicketsDemo tic1 = new TicketsDemo();  
  11.           
  12.         new Thread(tic1).start();  
  13.         new Thread(tic1).start();  
  14.         new Thread(tic1).start();  
  15.     }  
  16.   
  17. }  

虽然现在程序中有三个线程,但是三个线程一共才卖出了5张票。也就是说使用Runnable 实现的多线程可以达到资源共享的目的。

实际上 Runnable 接口和Thread 类之间还是存在联系的:


[java] view plaincopyprint?
  1. public class Thread extends Object implements Runnable  

发现Thread 类也是Runnable 接口的子类



原文: http://blog.csdn.net/iquicksandi/article/details/8470692

相关文章

    暂无相关文章
相关栏目:

用户点评