线程的创建方式

来源:互联网 发布:线程优化 编辑:程序博客网 时间:2024/05/30 19:33

创建线程有两种方式,一种是通过继承Thread类,覆盖run方法。另外一种是通过实现Runnable接口。

1 通过继承Thread类实现多线程

其步骤如下:
(1)定义类继承Thread类。
(2)覆盖Thread类中的run方法。
(3)通过Thread类的子类对象创建线程对象。
(4)调用线程对象的start方法,开启线程。
  其实线程要执行什么内容,线程自己便有定义,这个定义就是Thread中的run方法,这个方法中定义的内容就是线程要运行的内容。可是Thread中的run方法的内容并不是我们所需要的。怎么能让线程去运行我们自定义的内容呢?只有覆盖Thread类中的run方法,而覆盖之前需要先继承。这就是为什么要继承Thread类并覆盖run方法的原因。
主线程要运行的任务都在main函数中,自定义的线程要运行的任务都在run方法中。run方法就是专门用于存储线程任务代码的地方。
【例1.1】使用继承Thread类,覆盖run方法的方式创建线程。

ZiThread.java

//第一步:定义ZiThread类继承Thread类public class ZiThread extends Thread {    private String name;    ZiThread(String name)    {        this.name = name;    }//第二步:覆盖Thread类中的run方法    public void run(){      //将线程要运行的自定义的任务都封装到了run方法中        show();    }    public void show()    {        for(int x=1; x<=10; x++)        {for(int y=-99999999; y<99999999; y++){}//刻意写个循环让程序运行慢一点。            //Thread.currentThread():获取当前执行线程的对象              //getName()返回该线程的名称    System.out.println(x+":"+name+"-->"+Thread.currentThread().getName());        }    }}

ThreadDemo .java

public class ThreadDemo {    public static void main(String[] args) {        //第三步:通过Thread类的子类对象创建线程对象        ZiThread d1 = new ZiThread("旺财");//d1是线程对象        ZiThread d2 = new ZiThread("小明");//d2是线程对象        //第四步:调用线程对象的start方法,开启线程        d1.start();        d2.start();/*        线程光创建不行,还需要运行才会出现多条执行路径。         发现要运行线程,必须使用start方法。        start方法做了两件事:1,开启了线程让线程可以运行,2,调用了run方法。         */    }}

运行结果:
这里写图片描述
  线程对象的d1,d2调用run方法和调用start方法有什么区别呢?调用run方法,仅仅是一般对象在调用对象中的方法,并没有开启线程,还是主线程来完成的run方法的运行。调用start方法,是开启了一个线程(一个新的执行路径)这个线程去执行了run方法。
  下面模拟售票系统来举例说明。某售票点一共有100张票,通过四个窗口卖票。卖票的动作被四个窗口同时(线程思想)使用,那就需要创建线程。可通过继承Thread类,覆盖run方法。
【例1.2】通过继承Thread类实现多进程实例。

TicketWindows.java

//第一步:定义TicketWindows类继承Thread类public class TicketWindows extends Thread {    private int tickets=100;//第二步:复写父类Thread中run()方法    public void run() {        while(true){            if(tickets>0){                String name=Thread.currentThread().getName();                System.out.println(name+"正在发售第"+tickets--+"张票");            }        }    }}

NanJingStation.java

public class NanJingStation {    public static void main(String[] args) {//第三步:创建四个线程对象        NanJingStation s1=new NanJingStation();        NanJingStation s2=new NanJingStation();        NanJingStation s3=new NanJingStation();        NanJingStation s4=new NanJingStation();        s1.start();        s2.start();        s3.start();        s4.start();    }}

运行结果:
这里写图片描述

2 通过实现Runnable接口实现多线程

步骤:
(1)定义一个类,实现Runnable接口。
(2)覆盖Runnable接口中的run方法,将线程要运行的代码存储到run方法中。
(3)创建该接口的子类对象。
(4) 通过Thread类进行线程的创建,并将Runnable接口的子类对象作为Thread类的构造函数的实参进行传递。
   为什么要传递呢?这是为了让线程对象创建时,就要明确要运行哪个run方法,而这个run方法是需要被线程对象调用的,所以将run方法所属的对象传递给Thread类的构造函数。
(5)调用Thread类中的start方法开启线程。
【例2.1】通过实现Runnable接口实现多进程实例

TicketWindows.java

//第一步:定义TicketWindows类实现Runnable类public class TicketWindows implements Runnable {    private int tickets=100;//第二步:覆盖Runnable接口中的run方法    public void run() {        while(true){            if(tickets>0){                String name=Thread.currentThread().getName();                System.out.println(name+"正在发售第"+tickets--+"张票");            }        }    }}

NanJingStation.java

public class TicketWindows {    public static void main(String[] args) {        //第三步:创建任务对象        NanJingStation s=new NanJingStation();        /*第四步:创建线程对象(将子类NanJingStation中的对象作为实参传递,便于        知道调用的是哪个对象的run方法(这里只有一个对象t,调用的自然        是t中的run方法))       */        Thread t1=new Thread(s,"窗口1");//线程处于新建状态        Thread t2=new Thread(s,"窗口2");        Thread t3=new Thread(s,"窗口3");        Thread t4=new Thread(s,"窗口4");        //第五步:开启线程        t1.start();//线程处于就绪状态        t2.start();        t3.start();        t4.start();    }}

运行结果:
这里写图片描述
  为什么实现了Runnable接口还需要调用Thread类中的start()方法才能启动多线程呢?这是因为Runnable接口中只有一个run()方法。也就是说,Runnable接口中并没有start()方法,所以一个类实现了RunnableJ接口也必须用Thread类中的start()方法启动多线程。

3 两种多线程实现机制的比较

  从上面的售票实例可以看出,通过继承Thread类实现多线程时,要创建4个线程对象:

        NanJingStation s1=new NanJingStation();        NanJingStation s2=new NanJingStation();        NanJingStation s3=new NanJingStation();        NanJingStation s4=new NanJingStation();        s1.start();        s2.start();        s3.start();        s4.start();

  实际上是创建了4个线程对象——“南京站”,每个“南京站”有100张票。这4个线程对象各自占用各自的资源,无法达到资源共享的目的。再看通过实现Runnable接口实现多线程的方式,尽管也创建了4个线程对象(窗口),但是这里只建立了一个“南京站”,在这个“南京站”里开启了4个线程对象——窗口。它们都是操作同一个资源(“南京站”中的100张票),从而实现了资源共享的目的。

        NanJingStation s=new NanJingStation();        Thread t1=new Thread(s,"窗口1");        Thread t2=new Thread(s,"窗口2");        Thread t3=new Thread(s,"窗口3");        Thread t4=new Thread(s,"窗口4");        //第五步:开启线程        t1.start();        t2.start();        t3.start();        t4.start();

这里写图片描述

原创粉丝点击