JAVA学习笔记(三十二)

 

认识多线程


1.1  进程与线程


dos系统有一个非常明显的缺点,只要一中病毒之后系统会立刻死

机,因为传统的dos系统采用单进程的处理方式,所以只能有一个

程序独自运行,其他程序无法运行。


windows采用的事多进程的处理方式,在同一时间段同时运行多个

程序。


线程实际上就是在进程基础上的进一步划分。当然,会同时存在多

个线程。


如果一个进程没有了,则线程肯定会消失;
如果线程消失了,进程未必消失。
所有的线程都是在进程的基础上并发执行的。


进程是程序的一次动态执行过程,它经历了从代码加载,执行到执

行完毕的一个完整过程,这个过程也是进程本身从产生到最终消亡

的过程。


多线程是实现并发机制的一种有效手段。二者都是并发执行的一个

基本单位。


如果现在同时运行多个任务,则所有的系统资源都是共享的,被所

有线程所共有,但是程序处理需要CPU,传统的单核CPu,在同一个

时间段上会有多个程序执行,但是在同一时间点上只能存在一个程

序运行,也就是说,所有的程序都要抢占CPU资源。

但是现在的CPU已经发展到多核的状态了,在一个电脑上可能会存

在多个cpu。


1.2  java的多线程实现


在java中实现多线程的方式有两种:

:继承THread类

:实现Runnable接口

 

1.3 

线程 是程序中的执行线程。Java 虚拟机允许应用程序并发地运行

多个执行线程。

每个线程都有一个优先级,高优先级线程的执行优先于低优先级线

程。每个线程都可以或不可以标记为一个守护程序。当某个线程中

运行的代码创建一个新 Thread 对象时,该新线程的初始优先级被

设定为创建线程的优先级,并且当且仅当创建线程是守护线程时,

新线程才是守护程序。

当 Java 虚拟机启动时,通常都会有单个非守护线程(它通常会调

用某个指定类的 main 方法)。Java 虚拟机会继续执行线程,直

到下列任一情况出现时为止:

调用了 Runtime 类的 exit 方法,并且安全管理器允许退出操作

发生。
非守护线程的所有线程都已停止运行,无论是通过从对 run 方法

的调用中返回,还是通过抛出一个传播到 run 方法之外的异常。
创建新执行线程有两种方法。一种方法是将类声明为 Thread 的子

类。该子类应重写 Thread 类的 run 方法。接下来可以分配并启

动该子类的实例。例如,计算大于某一规定值的质数的线程可以写

成:

 

----------------------------------------------------------

----------------------

     class PrimeThread extends Thread {
         long minPrime;
         PrimeThread(long minPrime) {
             this.minPrime = minPrime;
         }
 
         public void run() {
             // compute primes larger than minPrime
              . . .
         }
     }
 
----------------------------------------------------------

----------------------

然后,下列代码会创建并启动一个线程:


     PrimeThread p = new PrimeThread(143);
     p.start();
 创建线程的另一种方法是声明实现 Runnable 接口的类。该类然

后实现 run 方法。然后可以分配该类的实例,在创建 Thread 时

作为一个参数来传递并启动。采用这种风格的同一个例子如下所示

 

----------------------------------------------------------

----------------------

     class PrimeRun implements Runnable {
         long minPrime;
         PrimeRun(long minPrime) {
             this.minPrime = minPrime;
         }
 
         public void run() {
             // compute primes larger than minPrime
              . . .
         }
     }
 
----------------------------------------------------------

----------------------

然后,下列代码会创建并启动一个线程:


     PrimeRun p = new PrimeRun(143);
     new Thread(p).start();
 每个线程都有一个标识名,多个线程可以同名。如果线程创建时

没有指定标识名,就会为其生成一个新名称。

 

从以下版本开始:
JDK1.0

 

 

1.4   A:THread类

THread类是在java.lang包中定义的,java.lang.Thread
,java.lang包会在程序运行时自动导入,所以无需手工编写imprt

语句。

一个类继承了Thread类之后,那么此类就具备了多线程的操作功能
在THread类中必须明确的覆写THread类中的run()方法 ,此方法

为线程的主体。

多线程的定义:

class 类名称 extends THread{
属性:
方法:

public void run()
{
线程主体;
}
}


class MyThread extends Thread
{
 private String name;
 public MyThread(String name){
 this.name = name;
 }
 public void run(){
 for( int i = 0;i < 10;i ++){
 System.out.println(name+"运行:i="+i);
 }
 }
};
public class ThreadDemo01
{
 public static void main(String args[]){
 MyThread th1 = new MyThread("线程A:");
 MyThread th2 = new MyThread("线程B:");
 th1.run();
 th2.run();
 }
}

结果:

F:\java\thread>java ThreadDemo01
线程A:运行:i=0
线程A:运行:i=1
线程A:运行:i=2
线程A:运行:i=3
线程A:运行:i=4
线程A:运行:i=5
线程A:运行:i=6
线程A:运行:i=7
线程A:运行:i=8
线程A:运行:i=9
线程B:运行:i=0
线程B:运行:i=1
线程B:运行:i=2
线程B:运行:i=3
线程B:运行:i=4
线程B:运行:i=5
线程B:运行:i=6
线程B:运行:i=7
线程B:运行:i=8
线程B:运行:i=9

问题:以上的程序是先执行A后在执行B,并没有并发执行;
因为以上的程序还是按照古老的形式调用的,但是如果要启动一个

线程,必须使用thread类中定义的srart()方法。

一旦调用start()方法,实际上最终调用的就死run()方法。

 

startpublic void start()

使该线程开始执行;Java 虚拟机调用该线程的 run 方法。
结果是两个线程并发地运行;当前线程(从调用返回给 start 方

法)和另一个线程(执行其 run 方法)。

多次启动一个线程是非法的。特别是当线程已经结束执行后,不能

再重新启动。


 

run
public void run()

如果该线程是使用独立的 Runnable 运行对象构造的,则调用该

Runnable 对象的 run 方法;否则,该方法不执行任何操作并返回


Thread 的子类应该重写该方法。


class MyThread extends Thread
{
 private String name;
 public MyThread(String name){
 this.name = name;
 }
 public void run(){
 for( int i = 0;i < 10;i ++){
 System.out.println(name+"运行:i="+i);
 }
 }
};
public class ThreadDemo01
{
 public static void main(String args[]){
 MyThread th1 = new MyThread("线程A:");
 MyThread th2 = new MyThread("线程B:");
 th1.start();
 th2.start();
 }
}

结果:

F:\java\thread>java ThreadDemo01
线程A:运行:i=0
线程B:运行:i=0
线程A:运行:i=1
线程B:运行:i=1
线程A:运行:i=2
线程B:运行:i=2
线程A:运行:i=3
线程B:运行:i=3
线程A:运行:i=4
线程B:运行:i=4
线程A:运行:i=5
线程B:运行:i=5
线程A:运行:i=6
线程B:运行:i=6
线程A:运行:i=7
线程B:运行:i=7
线程A:运行:i=8
线程B:运行:i=8
线程A:运行:i=9
线程B:运行:i=9


那么:


问什么不直接调用run()方法,而是通过start()方法调用呢?


查看thread类的定义,在JDK中的src.zip中全部都输java的源程序

代码,直接找到java.lang.Thread类,就可以打开Thread类的定义

 

public synchronized void start() {
        /**
  * This method is not invoked for the main method

thread or "system"
  * group threads created/set up by the VM. Any new

functionality added
  * to this method in the future may have to also

be added to the VM.
  *
  * A zero status value corresponds to state "NEW".
         */
        if (threadStatus != 0 || this != me)
            throw new IllegalThreadStateException();
        group.add(this);
        start0();
        if (stopBeforeStart) {
     stop0(throwableFromStop);
 }
    }

 


 

posted @ 2011-09-24 13:43  hibernate3例子  阅读(156)  评论(0编辑  收藏  举报