Thread类、Runnable接口

线程

线程的三种创建方式:

  • Thread class 继承Thread类(重点)
  • Runnable接口 实现Runnable接口(重点)
  • Callable接口 实现Callable接口(了解)

创建线程方法一步骤:

  1. 创建一个线程类,去继承Thread类
  2. 这个线程类立马重写run方法
  3. 实例化这线程个类,用实例化的对象去调用start方法执行线程。

主线程和子线程是同时、交替运行的

继承Thread类

  • 子类继承Thread类具备多线程能力
  • 启动线程方式:子类对象 .start();
  • 不建议使用:避免oop单继承局限性

实现Runnable接口

  • 实现接口Runnable具有多线程能力
  • 启动线程:传入实现类的实例化对象,到Thread类的构造方法中+.start();
  • 推荐使用:避免单继承局限性,灵活方法,方便同一个对象被多个线程使用

练习代码:

一、

package www.chen.com.thread;
//创建多线程方式一,继承Thread类
public class TestThread extends Thread{

    //重写run方法
    @Override
    public void run() {
        //run方法线程体
        for (int i = 0; i < 10; i++) {
            System.out.println("run方法"+i);
        }
    }

     public static void main(String[] args) {
        //创建一个线程对象,调用start方法
        TestThread testThread = new TestThread();
        testThread.start();

        //main线程,主线程
        for (int i = 0; i < 10; i++) {
            System.out.println("我在学习多线程"+i);
        }
    }
}

二、

package www.chen.com.thread;

import org.apache.commons.io.FileUtils;

import java.io.File;
import java.io.IOException;
import java.net.URL;

//练习thread,实现多线程同步下载图片
public class TestThread01 implements Runnable{

    private String url1;
    private String name1;

    //接收主线程的传参并赋值
    public TestThread01(String a,String b){

        this.url1 = a;
        this.name1 = b;

    }
    //子线程调用下载器这个类,并给下载器里的downloader方法传参
    @Override
    public void run() {
        WebDownloader webDownloader = new WebDownloader();
        webDownloader.downloader(url1,name1);
        System.out.println("成功下载了图片:"+name1);

    }


    public static void main(String[] args) {
        TestThread01 testThread01 = new TestThread01("https://www.baidu.com/img/PCpad_012830ebaa7e4379ce9a9ed1b71f7507.png","baidu.jpg");
        TestThread01 testThread02 = new TestThread01("https://img.kuyv.cn/201702/27/14-52-03-73-20.jpg","laopo1.jpg");
        TestThread01 testThread03 = new TestThread01("https://img.kuyv.cn/201702/27/14-48-14-53-20.jpg","laopo2.jpg");
        new Thread(testThread01).start();
        new Thread(testThread02).start();
        new Thread(testThread03).start();

    }

}

//下载器 类
class WebDownloader{
    //方法
public void downloader(String url,String name){
    //实现代码
        try {
            FileUtils.copyURLToFile(new URL(url),new File(name));
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("下载器执行成功,但是编译异常");
        }
    }
}

三、

package www.chen.com.thread;

//创建线程方式二,实现Runnable接口,重写run方法,执行线程需要丢入Runnable接口实现类,调用start()方法
public class TestThread2 implements Runnable{
    //重写run方法
    @Override
    public void run() {
        //run方法线程体
        for (int i = 0; i < 20; i++) {
            System.out.println("run方法"+i);
        }
    }

    public static void main(String[] args) {
        //实例化实现类
        TestThread2 testThread2 = new TestThread2();
        //实例化Thread这个类,将实现类的实例化对象,丢到Thread这个类的构造方法中去。
        //testThread2这里叫Runnable接口的目标对象
//        Thread thread = new Thread(testThread2);
//        //调用start方法
//        thread.start();
        //简写上面的代码
        new Thread(testThread2).start();


        //main线程,主线程
        for (int i = 0; i < 1000; i++) {
            System.out.println("我在学习多线程"+i);
        }
    }
}

四、

package www.chen.com.thread;
//龟兔赛跑
public class Race01 implements Runnable{

    private static String winner;
    //设置赛道长度
    @Override
    public void run() {
        for (int i = 0; i <= 1000; i++) {
            //设置兔子睡觉的时间
            //如果来的是兔子,那么每10m兔子将休息10ms
            if (Thread.currentThread().getName().equals("兔子")&& i%50==0){
                //sleep会报异常
                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

            //判断比赛是否结束
            boolean flag = gameOver(i);
            if (flag){
                break;
            }
            //输出谁跑了多少步
            System.out.println(Thread.currentThread().getName()+"--->跑了"+i+"步");
        }
    }
    //写一个私有方法,判断是否完成比赛
    private boolean gameOver(int a) {
        if (winner != null) {//如果winner不为空,那么比赛结束了
            return true;
        }{
            if (a >= 1000) {
                winner = Thread.currentThread().getName();
                System.out.println("winner is: " + winner);
                return true;
            }
            return false;
        }
    }
    //主线程调用子线程
    public static void main(String[] args) {
        Race01 race01 = new Race01();
        new Thread(race01,"兔子").start();
        new Thread(race01,"乌龟").start();

    }

}
posted @ 2021-03-11 17:43  恶的反思  阅读(104)  评论(0)    收藏  举报