java的多线程(一)

     我们知道我们打开个程序(或者说运行一款软件)其实也就是创建了一个进程,只不过程序是静态指令的集合,而进程是正在系统中运行的指令集合,进程是系统进行资源分配与调度的一个独立单位。进程具有独立性,动态性,并发性。现在的操作系统都支持并发,但在具体实现的细节上,根据硬件和操作系统的不同存在不同的策略,比较常用的方式有:共用式的多任务操作策略,抢占式的多任务策略。

    线程扩展了进程的概念,线程是进程的执行单元,线程在进程中也是独立存在的,是一种并发的执行流,当进程被初始化之后,主线程就被创建出来了。对于绝大多数程序来说只有一个主线程,我们可以同时创建多条线程顺序执行流也就是线程。也就是说线程是进程的组成部分,一个进程可以拥有多个线程,一个线程必须有一个父进程。线程可以拥有自己的堆栈,自己的计数器,自己的局部变量等。但他们不在拥有系统资源,而是与其他线程之间共享该进程所拥有的所有的资源。线程用来完成一定的任务,可与其他线程之间共享父进程中的共享变量及部分环境,相互之间协同来完成进程所要完成的工作。

    简单来说:一个程序运行后至少有一个进程,一个进程里可以包含多个线程,但至少包含一个线程。

线程的创建和启动:

Java使用Thread类代表线程,所有的线程对象都必须是Thread类或其子类的实例,每条线程的任务就是完成一定的任务,实际就是执行一段程序流,而java使用run方法来封装这段程序流。接下来介绍两种创建线程的方法。

第一种继承Thread类来创建线程类:

1、定义Thread类的子类,并重写Thread类的run方法,这个run方法的方法体就代表了线程需要完成的任务,就是线程执行体了。

2、创建Thread类子类的实例,也就是创建线程对象。

3、用线程的start方法来启动线程。

下面是一个具体的例子:

/**
 * 
 */
package cn.wan;
/**
 * @author Administrator
 *
 */
public class TestHread extends Thread{

    private int i;
    
    public void run()
    {
        for(;i<20;i++)
        {
            System.out.println(getName()+""+i);
        }
    }
    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub

        for(int i = 0;i<100;i++)
        {
            System.out.println(Thread.currentThread().getName()+""+i);
            if(i== 20)
            {
                new TestHread().start();
                System.out.println("AAAAAAAAAAAAAAAAAAAAAAAAAA");
                new TestHread().start();
            }
        }
    }

}

当Java程序运行时,至少会创建一个线程,那就是主线程,主线程的线程执行体不是由run方法来确定的,而是由main方法来确定的。main方法的方法体代表主线程的线程执行体。

第二种实现Runnable接口创建线程类

1、定义Runnable接口的实现类并重写该接口的run方法,该run方法的方法体同样是该线程的线程执行体。

2、创建Runnable实现类的实例,并以此实例来作为Thread类的target来创建Thread对象。这个Thread类的实例才是真正的线程对象。

//   创建Runnable接口实现的对象,SecondThread类实现了这个接口,
   SecondThread st = new   SecondThread();
   Thread th = new Thread(st);

下面是一个具体有的例子:

package cn.wan;

public class SecondThread implements Runnable{


    private int i;
    @Override
    /**
     * run方法同样是线程的执行体
     */
    public void run() {
        // TODO Auto-generated method stub
        for(;i<100;i++)
        {
            // 当线程类实现Runnable接口时
            // 如果想获得当前线程,只能用Tread.currentThread()方法
            System.out.println(Thread.currentThread().getName()+""+i);
        }
        
    }

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub

        for(int i = 0;i<100;i++)
        {
            System.out.println(Thread.currentThread().getName()+""+i);
            if(i== 20)
            {
                SecondThread st = new SecondThread();
                //  通过new Thread(target,name)方法创建新线程
                new Thread(st,"first one").start();
                System.out.println("AAAAAAAAAAAAAAAAAAAAAAAAAA");
                new Thread(st,"second one").start();
            }
        }
    }
}

第一种和第二种方法主要差别在:

第一种

劣势:因为线程类已经继承了Thread类,所以不能再继续继承父类。

优势:编写简单,如果需要访问当前进程只需使用this关键字即可。无需使用Thread.currentThread方法。

第二种

劣势:编写复杂,如果需要访问当前线程需要使用Thread.currentThread方法。

优势:线程类只是继承了Runnable接口,还可以继承其他类。同时多线程可以同时共享同一个target对象,所以非常适合多个相同线程来处理同一份资源的情况。

 

posted @ 2015-03-28 19:14  都市烟火  阅读(255)  评论(0编辑  收藏  举报