zoukankan      html  css  js  c++  java
  • Java多线程(二)——常用的实现多线程的两种方式

    一、继承Thread类创建线程类

         Java使用Thread类代表线程,所有的线程对象都必须是Thread类或其子类的实例。每个线程的作用是完成一定的任务,实际上就是执行一段程序流即一段顺序执行的代码。Java使用线程执行体来代表这段程序流。

    Thread类的声明如下:

    public class Thread implements Runnable {}

    可以看到,Thread本身就实现了Runnable接口。

    Java中通过继承Thread类来创建并启动多线程的步骤如下:

    01. 定义Thread类的子类,并重写该类的run()方法,该run()方法的方法体就代表了线程需要完成的任务,因此把run()方法称为线程执行体。

    02. 创建Thread子类的实例,即创建了线程对象。

    03. 调用线程对象的start()方法来启动该线程。

    示例:

    package com.demo;
    
    //通过继承Thread类来创建线程类
    public class MyThread extends Thread{
    
        private int ticket = 10;
        
        //重写run方法
        public void run(){
            for(int i=0;i<20;i++){
                if(this.ticket>0){
                    System.out.println(this.getName()+" 卖票:ticket"+this.ticket--);
                }
            }
        }
        
        public static void main(String[] args) {  
            // 启动3个线程t1,t2,t3;每个线程各卖10张票!
            MyThread t1=new MyThread();
            MyThread t2=new MyThread();
            MyThread t3=new MyThread();
            t1.start();
            t2.start();
            t3.start();
        }  
    }

    运行结果:

    Thread-0 卖票:ticket10
    Thread-0 卖票:ticket9
    Thread-0 卖票:ticket8
    Thread-0 卖票:ticket7
    Thread-1 卖票:ticket10
    Thread-1 卖票:ticket9
    Thread-1 卖票:ticket8
    Thread-1 卖票:ticket7
    Thread-1 卖票:ticket6
    Thread-0 卖票:ticket6
    Thread-0 卖票:ticket5
    Thread-0 卖票:ticket4
    Thread-0 卖票:ticket3
    Thread-0 卖票:ticket2
    Thread-0 卖票:ticket1
    Thread-2 卖票:ticket10
    Thread-2 卖票:ticket9
    Thread-2 卖票:ticket8
    Thread-2 卖票:ticket7
    Thread-2 卖票:ticket6
    Thread-2 卖票:ticket5
    Thread-2 卖票:ticket4
    Thread-2 卖票:ticket3
    Thread-2 卖票:ticket2
    Thread-1 卖票:ticket5
    Thread-2 卖票:ticket1
    Thread-1 卖票:ticket4
    Thread-1 卖票:ticket3
    Thread-1 卖票:ticket2
    Thread-1 卖票:ticket1

    结果说明
    (01) MyThread继承于Thread,它是自定义个线程。每个MyThread都会卖出10张票。
    (02) 主线程main创建并启动3个MyThread子线程。每个子线程都各自卖出了10张票。

    二、实现Runnable接口创建线程类

    Runnable 是一个接口,该接口中只包含了一个run()方法。它的定义如下:

    public interface Runnable {
        public abstract void run();
    }

    实现Runnable接口来创建并启动多线程的步骤如下:

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

    02. 创建Runnable实现类的实例,并以此实例作为Thread的target来创建Thread对象,该Thread对象才是真正的线程对象。

    03. 调用线程对象的start()方法来启动线程。

    需要注意的是:Runnable对象仅仅作为Thread对象的target,Runnable实现类里包含的run()方法仅作为线程执行体。而实际的线程对象依然是Thread实例,只是该Thread线程负责执行其target的run()方法。

    示例:

    package com.demo;
    
    //通过实现Runnable接口创建多线程
    public class MyThread1 implements Runnable{
        
        private int ticket = 10;
        
        public void run(){
            for(int i=0;i<20;i++){
                if(this.ticket>0){
                    System.out.println(Thread.currentThread().getName()+" 卖票:ticket"+this.ticket--);
                }
            }
        }
        
        public static void main(String[] args) {  
            MyThread1 mt=new MyThread1();
    
            // 启动3个线程t1,t2,t3(它们共用一个Runnable对象),这3个线程一共卖10张票!
            Thread t1=new Thread(mt);
            Thread t2=new Thread(mt);
            Thread t3=new Thread(mt);
            t1.start();
            t2.start();
            t3.start();
        }  
    
    }

    运行结果:

    Thread-0 卖票:ticket10
    Thread-0 卖票:ticket8
    Thread-0 卖票:ticket7
    Thread-1 卖票:ticket9
    Thread-2 卖票:ticket5
    Thread-0 卖票:ticket6
    Thread-1 卖票:ticket4
    Thread-2 卖票:ticket3
    Thread-1 卖票:ticket1
    Thread-0 卖票:ticket2

    结果说明
    (01) 和上面“MyThread继承于Thread”不同;这里的MyThread1实现了Thread接口。
    (02) 主线程main创建并启动3个子线程,而且这3个子线程都是基于“mt这个Runnable对象”而创建的。运行结果是这3个子线程一共卖出了10张票。这说明它们是共享了MyThread接口的。

    三、Thread和Runnable的异同点

    Thread 和 Runnable 的相同点:都是“多线程的实现方式”。
    Thread 和 Runnable 的不同点:
    Thread 是类,而Runnable是接口;Thread本身是实现了Runnable接口的类。我们知道“一个类只能有一个父类,但是却能实现多个接口”,因此Runnable具有更好的扩展性。
    此外,Runnable还可以用于“资源的共享”。即,多个线程都是基于某一个Runnable对象建立的,它们会共享Runnable对象上的资源。
    通常,建议通过“Runnable”实现多线程!

  • 相关阅读:
    Maven 环境的配置
    zTree的简单例子
    plsql免安装客户端的配置
    HDU 1232 畅通工程
    HDU 5698 瞬间移动
    Codeforces 1015E1 Stars Drawing (Easy Edition)
    Codeforces 784B Santa Claus and Keyboard Check
    Codeforces 500C New Year Book Reading
    NSarray 赋值 拷贝 等问题记录
    UINavigationController 操作记录
  • 原文地址:https://www.cnblogs.com/xiaoxi/p/6481443.html
Copyright © 2011-2022 走看看