您的位置:首页 > 职场人生

黑马程序员-多线程部分(一.创建)

2015-10-11 14:02 218 查看
——- android培训java培训、期待与您交流! ———

学习多线程之前,我们需要知道为什么要学习多线程?首先需要明确以下三点内容:

 

第一点: 什么是进程?什么是线程?

任何一个应用程序开启后都是一个进程,进程是由window/linux系统启动的。线程是进程开启后运行的操作控制单元,或者称为执行路径, 一个进程至少有一个线程。对于任何一个java程序,实际上开启的是两个线程,一个是main顺序执行的顺序线程,一个是系统自带的gc垃圾回收线程。这样做的好处是一方面保证了内存的空间,一方面保证了运行速度不受影响。

第二点:多线程的理解?

当一个进程中开启多个线程时,显示的为这多个线程同时在执行,而实际上如果只有一个CPU处理器时,CPU是随机选择执行某一个线程的,由于CPU高速切换的特性,看起来好像多个线程在同时执行,这是看哪个线程率先抢占CPU的执行权,但在某一时刻,一个CPU是只执行一个线程的。 多线程就是一个线程里面有两个或两个以上线程可以一起执行,都具备CPU执行资格,也都可以轮流运行。

第三点:多线程的作用?

多线程可以使多个程序同时运行,提高了运行效率。

明白以上三点,首先我们学校多线程的创建方式。

一个线程的创建方式有两种:

(一)使用Thread类完成,创建步骤如下:

步骤一:一个子类继承Thread类

步骤二:覆写run方法

[code]class Test extends Thread
{
    void run()
    {
        for(int i=0;i<100;i++)
        {
            System.out.println("test......."+i);
        }
    }
}


步骤三:实例化对象,调用start方法。

[code]public class ThreadDemo
{
    public static void main(String args[])
    {
        Test test = new Test();
        test.start();
        for(int i=0;i<90;i++)
        {
            System.out.println("main......."+i);
        }
    }
}


运行结果如下:




main线程和test线程交替运行。

在这里,多线程执行的是run()方法里面的代码块,调用start()方法有两个作用,一是开启该线程,二是调用run()方法。此处不应该直接调用run()方法,如下代码会出现错误:

[code]public class ThreadDemo
{
    public static void main(String args[])
    {
        Test test = new Test();
        test.run();
        for(int i=0;i<90;i++)
        {
            System.out.println("main......."+i);
        }
    }
}


运行结果:




显示为先执行test的run方法,后执行main以后的代码,此为单线程。

需要说明一点:如果没有调用start方法,实际上等于没有开启多线程,只是简单的在main线程中调用run方法而已,实际上只有一个main线程,而非是多线程。

(二)实现runnable接口,开启线程。 实现步骤如下 :

步骤一:实现runnable接口

步骤二:覆写runnable接口中的run方法 。

[code]class Test implements Runnable
{
    public void run()
    {
        for(int i=0;i<100;i++)
        {
            System.out.println("test......."+i);
        }
    }
}


步骤三:实例化实现runnable接口的子类对象

步骤四:实例化Thread类,并把实现runnable接口的子类对象传递到构造方法中

步骤五:调用启动线程方法start()

[code]public class ThreadDemo
{
    public static void main(String args[])
    {
        Test test = new Test();
        Thread t = new Thread(test);
        t.start();
        for(int i=0;i<90;i++)
        {
            System.out.println("main......."+i);
        }
    }
}


在这里,与Thread唯一的不同是,在Thread实例化时,将runnable接口的子类传入到构造方法中即可实现。

以上两种方法为简单的创建多线程,那么二者有什么区别和联系呢?

1). 如果该类继承了其他类,则不可继承Thread类;或者继承了Thread类则不可继承其他类,而使用runnable接口则不会出现这种情况,避免了单继承的局限。

2). 使用runnable接口,则可以实现资源共享。不用定义为static即可。

一般情况,建议使用runnable接口的方法开启线程。

第一点比较容易理解,下面看一下第二点,利用代码说明。

例子:一共50张票,4个窗口同时买票。

首先用Thread实现:

[code]class Test extends Thread
{
    private int ticket = 50;
    public void run()
    {
        while(true)
        {
            if(ticket>0)
            {
            System.out.println("ticket......."+ticket--);
            }
        }

    }
}


[code]public class ThreadDemo
{
    public static void main(String args[])
    {
        Test t1 = new Test();
        Test t2 = new Test();
        Test t3 = new Test();
        Test t4 = new Test();
        t1.start();
        t2.start();
        t3.start();
        t4.start();

    }
}


运行结果如下:




结果显示,四个线程分别执行了50张票,没有共享数据,造成数据错误。

在此用Runnable实现:

[code]class Test implements Runnable
{
    private int ticket = 50;
    public void run()
    {
        while(true)
        {
            if(ticket>0)
            {
            System.out.println("ticket......."+ticket--);
            }
        }

    }
}


[code]public class ThreadDemo
{
    public static void main(String args[])
    {
        Test test = new Test();
        Thread t1 = new Thread(test);
        Thread t2 = new Thread(test);
        Thread t3 = new Thread(test);
        Thread t4 = new Thread(test);
        t1.start();
        t2.start();
        t3.start();
        t4.start();

    }
}


运行结果如下:




而一个Runnable子类被传递到四个线程中,可以共享数据,从而避免了数据错误。

好了,到此为止,多线程创建部分已经完成了,下一集介绍多线程的多线程的数据安全问题,利用线程同步来解决。敬请期待。 本人也是初学者,有什么问题请指出,共同商讨。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: