多线程详解

2022/8/3 6:23:50

本文主要是介绍多线程详解,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!


1. 线程简介

 简介
任务 本质上在同一时间做了一件事情。吃饭玩手机,开车打电话。
进程(Process) 在操作系统中运行的程序。是执行程序的一次执行过程,动态概念。
程序(Thread) 指令和数据的有序集合,本身没有任何运行的含义,静态概念。
线程 一个进程中可以包含若干个线程,一个进程中至少有一个线程。
多线程 从软件或者硬件上实现多个线程并发执行的技术。王者荣耀开黑。

普通方法调用和多线程调用,如图:

2. 线程实现(重点)

1. 继承Thread class

//   步骤:
//   1. 自定义线程类继承Thread类
//   2. 重写run()方法,编写线程执行体
//   3. 创建线程对象,调用start()方法启动
//注意:线程开启不一定不一定立即执行,由CPU调度执行
//创建线程方式一: 继承Thread类, 重写run()方法,调用Start()开启线程。(start()方法线程同时执行)
public class TestThread extends Thread {
    @Override
    public void run() {        //run方法线程体
        for (int i = 0; i < 20; i++) {
            System.out.println("我在看代码----run----" + i);
        }
    }
​
    public static void main(String[] args) {        //main线程, 主线程
        TestThread t1 = new TestThread();
        t1.start();                  //创建线程对象,调用start()方法开启线程
//        new t1().start();        //创建线程对象,调用start()方法开启线程
//        new t1().run();        //先执行run方法。
        for (int i = 0; i < 20; i++) {
            System.out.println("我在学习多线程----main----" + i);
        }
    }
}

 

2. 实现 Runable 接口

//   步骤
//   1. 定义MyRunnable类实现Runnable接口 
//   2. 实现run()方法,编写线程执行体
//   3. 创建线程对象,调用start()方法启动线
/创建线程方式2: 实现runnable接口, 重写run方法, 执行线程需要将runnable实现类对象丢入Thread中, 调用Start()方法。
//runnable里面没有start()方法, 所以需要开启线程的时候, 需要借用Thread类中的Start()方法。
public class TestRunnable implements Runnable {
​
    @Override
    public void run() {        //run方法线程体
        for (int i = 0; i < 20; i++) {
            System.out.println("我在看代码----run----" + i);
        }
    }
​
    public static void main(String[] args) {        //main线程, 主线程
        TestRunnable T3 = new TestRunnable();//创建runnable接口的实现类对象
​
​
//        Thread thread = new Thread(T3);       //创建线程对象,通过线程对象代理开启我们的线程。
//        thread.start();                       //创建线程对象,通过线程对象代理开启我们的线程。
        new Thread(T3).start();               //创建线程对象,通过线程对象代理开启我们的线程。
​
​
        for (int i = 0; i < 20; i++) {
            System.out.println("我在学习多线程----main----" + i);
        }
    }
}

 

扩展:网页下载器

  1. 下载jar包,编写工具类

class WebDownloader {        //文件下载工具类
    public void downloader(String url, String name) {    //远程路径  下载名字
        try {
            //FileUtils: 文件工具,复制url到文件
            //Commons IO: 针对开发IO流功能的工具库
            FileUtils.copyURLToFile(new URL(url), new File(name));  //将网络上的一个网页地址变为一个文件
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("IO异常,downloader方法下载异常。");
        }
    }
}

 

  1. 继承Thread类,重写run方法

class TestThread extends Thread {          //练习Thread, 实现多线程同步下载图片。
    private String url;     //网络图片地址
    private String name;    //保存的文件名
​
    public TestThread(String url, String name){   //构造器
        this.url=url;
        this.name=name;
    }
​
    @Override
    public void run() {    //下载图片线程的执行体。
        WebDownloader webDownloader = new WebDownloader();
        webDownloader.downloader(url,name);
        System.out.println("下载的文件名为:"+name);
    }
​
}

 

  1. 创建类对象,实现多线程

     public static void main(String[] args) {        //main方法
        TestThread2 T1 = new TestThread2("https://img3.doubanio.com/view/note/l/public/p83642840.webp","1.jpg");
        TestThread2 T2 = new TestThread2("https://img3.doubanio.com/view/note/l/public/p83642840.webp","2.jpg");
        TestThread2 T3 = new TestThread2("https://img3.doubanio.com/view/note/l/public/p83642840.webp","3.jpg");
        T1.start();
        T2.start();
        T3.start();
    }

 

完整代码

通过实现Thread类实现
class TestThread extends Thread {          //练习Thread, 实现多线程同步下载图片。
    private String url;     //网络图片地址
    private String name;    //保存的文件名
​
    public TestThread(String url, String name){   //构造器
        this.url=url;
        this.name=name;
    }
    
    @Override
    public void run() {    //下载图片线程的执行体。
        WebDownloader webDownloader = new WebDownloader();
        webDownloader.downloader(url,name);
        System.out.println("下载的文件名为:"+name);
    }
​
    public static void main(String[] args) {        //main方法
        TestThread T1 = new TestThread("https://img3.doubanio.com/view/note/l/public/p83642840.webp","1.jpg");
        TestThread T2 = new TestThread("https://img3.doubanio.com/view/note/l/public/p83642840.webp","2.jpg");
        TestThread T3 = new TestThread("https://img3.doubanio.com/view/note/l/public/p83642840.webp","3.jpg");
        T1.start();
        T2.start();
        T3.start();
    }
}

 

通过实现Runnalbe接口实现
class Testrunnable implements Runnable {          //练习Thread, 实现多线程同步下载图片。
    private String url;     //网络图片地址
    private String name;    //保存的文件名
​
    public Testrunnable(String url, String name) {   //构造器
        this.url = url;
        this.name = name;
    }
​
    @Override
    public void run() {    //下载图片线程的执行体。
        WebDownloader webDownloader = new WebDownloader();
        webDownloader.downloader(url,name);
        System.out.println("下载的文件名为:"+name);
    }
​
    public static void main(String[] args) {        //main方法
        Testrunnable T4 = new Testrunnable("https://img3.doubanio.com/view/note/l/public/p83642840.webp", "4.jpg");
        Testrunnable T5 = new Testrunnable("https://img3.doubanio.com/view/note/l/public/p83642840.webp", "5.jpg");
        Testrunnable T6 = new Testrunnable("https://img3.doubanio.com/view/note/l/public/p83642840.webp", "6.jpg");
​
        new Thread(T4).start();
        new Thread(T5).start();
        new Thread(T6).start();
    }
}

 

扩展:龟兔赛跑

public class Race implements Runnable {
    
    private static String winner; //胜利者
    
    @Override
    public void run() {
        for (int i = 1; i <= 100; i++) {
            //模拟兔子休息200ms
            if ((Thread.currentThread().getName().equals("兔子")) && (i % 10 == 0)) {
                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            //判断比赛是否结束
            boolean flag = gameOver(i);
            if (flag) {
//                System.out.println(Thread.currentThread().getName()+"-->跑了"+i+"米。");
                break;
            }
            System.out.println(Thread.currentThread().getName() + "-->跑了" + i + "米");
        }
    }
    //判断是否完成比赛
    private boolean gameOver(int steps) {
        if (winner != null) {
            return true;
        } else if (steps == 100) {
            winner = Thread.currentThread().getName();
            System.out.println("winner is ---> " + winner);
            return true;
        }
        return false;
    }
​
    public static void main(String[] args) {
        Race race = new Race();
        new Thread(race, "乌龟").start();
        new Thread(race, "兔子").start();
    }
}

 


扩展:购买火车票

//多个线程同时操作一个对象
//发现问题: 多个线程操作同一个资源的情况下, 线程不安全, 数据紊乱。
//出现多个人抢到同一张票。
//Thread.currentThread().getName()   查看是哪个线程正在操作(当前运行线程的名字)
public class TestRunnable implements Runnable{
​
    private int ticketNums = 10; //票数
​
    @Override
    public void run() {
        while (true) {
            if (ticketNums < 1) {
                break;
            }
            try {       //模拟延迟。
                Thread.sleep(200);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName()+"---->>拿到了第"+(ticketNums--)+"票。");
        }
    }
​
    public static void main(String[] args) {
        TestRunnable testThread4 = new TestRunnable();
        //开启3个线程处理同一资源
        new Thread(testThread4,"小明").start();
        new Thread(testThread4,"小红").start();
        new Thread(testThread4,"黄牛").start();
    }
}

 

 

初识并发问题

Thread-Runnable的小结:

继承Thread类实现Runnable接口
子类继承Thread类具备多线程能力 实现接口Runnable具有多线程能力
启动线程:子类对象.Start() 传入目标对象+Thread对象.Start()
不建议使用:避免OOP单继承局限性 推荐使用:避免OOP单继承局限性,灵活方便,方便同一个对象被多个线程使用。

3. 实现Callable(了解)

//   步骤
//   1. 实现Callable接口,需要返回值类型
//   2. 重写call方法,需要抛出异常
//   3. 创建目标对象
//   4. 创建执行服务:ExecutorService ser = Executors.newFixedThreadPool(1);
//   5. 提交执行:Future<Boolean> result1 = ser.submit(t1);
//   6. 获取结果:boolean r1 = result1.get()
//   7. 关闭服务:ser.shutdownNow()

 

3. 线程状态

4. 线程同步(重点)

5. 线程通信问题

6. 高级主题



这篇关于多线程详解的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程