认识多线程

目录

 

一 、进程 与 线程

二 、Java中多线程的实现

 1 、继承 Thread 类实现多线程

 2 、实现 Runnable 接口实现多线程

三 、通过 Thread 类 和 Runnable 接口实现多线程的区别

 1 、继承 Thread 类不能资源共享

2 、实现 Runnable 接口实现资源共享


 

一 、进程 与 线程

进程是程序的一次动态的执行过程。多进程系统可以同时运行多个进程(也就是程序),而线程是比进程更小的执行单位,比如运行一个听歌的软件(进程),播放歌曲就是其中一个线程,搜索歌曲也是一个线程,浏览评论也是一个线程

多线程是指一个进程在执行过程中可以产生多个线程,这些线程可以同时存在,同时运行,所以一个进程可能包含了多个同时执行的线程。

多线程是实现并发机制的一种有效手段

 

二 、Java中多线程的实现

在Java中要想实现多线程代码有两种方法:

【1】继承 Thread 类

【2】实现 Runnable 接口

 1 、继承 Thread 类实现多线程

Thread 类是在Java.lang包中定义,一个类如果继承了 Thread 类,此类就称为多线程操作类,在Thread子类中,必须明确地覆写 run() 方法,并通过 start() 方法启动线程

class MyThread extends Thread{  //继承Thread类
    private String name;
    public MyThread(String name){
        this.name = name;
    }
    public void run(){    //覆写Thread类中的run()方法
        for (int i=0; i<10; i++){
            System.out.println(name + "运行,i = " + i);
        }
    }
}

public class ThreadDemo01 {
    public static void main(String[] args) {
        MyThread mt1 = new MyThread("线程A");
        MyThread mt2 = new MyThread("线程B");
        mt1.start();   //调用start()方法启动线程
        mt2.start();   //调用start()方法启动线程
    }
}

程序运行结果(可能的一种结果):

从程序的运行结果可以发现,两个线程交替运行,哪个线程对象抢到了CPU资源,哪个线程就可以运行,所以程序每次的运行结果都不一样

提问:为什么启动线程必须通过start()方法启动,而不能直接调用 run() 方法呢?

回答:由于多线程的实现需要依靠底层操作系统得支持,start() 方法除了会调用run() 方法,还有一些调用本机操作系统的函数。另外,一个线程对象只能调用一次start()方法,调用一次便可以启动多线程,如果调用多次,则会抛出异常

 继承 Thread 类可以实现多线程,但会受到单继承局限的影响,所以,还可以通过实现Runnable接口实现多线程

 

 

 2 、实现 Runnable 接口实现多线程

查阅JDK文档发现,Runnable 接口只定义了一个 run() 方法

要想启动一个多线程必须使用 start() 方法完成,那么此时该如何启动多线程呢?

查阅JDK文档的Thread类发现其有构造方法可以接收Runnable的子类实例对象,所以就可以依靠此点启动多线程

实现Runnable接口,通过Thread类启动多线程

class MyThread implements Runnable{  //实现Runnable接口
    private String name;
    public MyThread(String name){
        this.name = name;
    }
    public void run(){    //覆写Runnable接口中的run()方法
        for (int i=0; i<10; i++){
            System.out.println(name + "运行,i = " + i);
        }
    }
}

public class RunnableDemo01 {
    public static void main(String[] args) {
        MyThread mt1 = new MyThread("线程C"); //实例化Runnable子类对象
        MyThread mt2 = new MyThread("线程D"); //实例化Runnable子类对象
        Thread t1 = new Thread(mt1);     //实例化Thread类对象
        Thread t2 = new Thread(mt2);     //实例化Thread类对象
        t1.start();     //启动线程
        t2.start();     //启动线程
    }
}

程序运行结果(可能的一种结果):

 

 

三 、通过 Thread 类 和 Runnable 接口实现多线程的区别

 使用 Thread 类实现多线程时无法实现资源共享,而实现 Runnable 接口实现多线程可以实现资源共享

 1 、继承 Thread 类不能资源共享

class MyThread extends Thread{
    private int ticket = 5;  //一共有5张票
    public void run(){
        for (int i=0; i<100; i++){
           if (ticket>0){   //判断是否有余票
               System.out.println("卖票:ticket = " + ticket--);
           }
        }
    }
}

public class ThreadDemo02 {
    public static void main(String[] args) {
        MyThread mt1 = new MyThread();
        MyThread mt2 = new MyThread();
        MyThread mt3 = new MyThread();
        mt1.start();
        mt2.start();
        mt3.start();
    }
}

程序运行结果:

从程序的运行结果可以发现,每个线程都各自卖自己的5张票,没有达到资源共享

 

2 、实现 Runnable 接口实现资源共享

class MyThread implements Runnable{
    private int ticket = 5; //一共5张票
    public void run(){
        for (int i=0; i<100; i++){
            if (ticket>0){  //判断是否有余票
                System.out.println("卖票:ticket = " + ticket--);
            }
        }
    }
}

public class RunnableDemo02 {
    public static void main(String[] args) {
        MyThread mt = new MyThread();
        //启动3个线程
        new Thread(mt).start();
        new Thread(mt).start();
        new Thread(mt).start();
    }
}

程序运行结果:

3个线程一共卖了5张票

 

实现 Runnable 接口相对于继承 Thread类来说,有如下优势:

【1】适合多个相同程序代码的线程去处理同一资源的情况

【2】可以避免由于Java的单继承特性带来的局限

【3】增强了程序的健壮性,代码能够被多个线程共享,代码与数据是独立的

所以在开发中建议使用 Runnable 接口实现多线程

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值