java多线程

多线程详解 java Thread

1.线程的简介

1.任务,进程,线程,多线程

多任务:一个人在一段时间内看起看来向进行许多任务,但是其实真正大脑只在执行一个任务

多线程:

多分支和多线程

普通方法调用一个函数,其实是在顺序执行,没有办法同时执行,而多线程就可以

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-y7zNveJB-1651654409852)(${images}/image-20210514104314760.png)]

进程:在操作系统中运行中的程序就是进程,比如qq,播放器,

一个进程可以有多个线程,如视频中同时听声音,看图像,看弹幕,等等

2.Process和Thread

Process(进程)

Thread(线程)

  • 说起进程,就必须说到程序。程序是指令和数据的有序集合,本身没有任何运行的含义,是一个静态的概念
  • 进程,是动态的,是系统分配资源的单位
  • 通常一个进程包含若干个线程,线程是cpu调度和执行的单位

注意!很多多线程都是模拟出来的,真正的多线程应该是多个cpu执行多个任务,即多核

模拟出来的cpu,在同一时间,cpu只能执行一个代码,但是切换的很快,所以有了同时执行的错觉

main()主线程,gc线程(垃圾回收)

本章核心

  • 线程就是独立的执行路径
  • 在程序执行时,即使没有自己创建线程,后台也会有多个线程,如主线程,gc线程
  • main()称之为主线程,位系统的入口,用于执行整个程序
  • 在一个进程中如果开辟了多个线程,那么线程的运行有调度器安排调度,
  • 对于同一份资源操作时,会存在资源抢占,需要假如并发控制
  • 线程会带来额外的开销,如cpu的调度时间,并发控制开销
  • 每个线程在自己工作的内存交互,内存控制不当会造成数据不一致

2.线程的创建(重点)

Thread,Runable,Callable

main用户线程

gc守护线程

1.三种创建方式

Thread class继承Thread类(重点)
Runnable接口impl(重要)实现Runnable接口(重点)
Callable接口Callable接口(了解)
3.1Thread实现
  1. 创建一个类继承Thread
  2. 重写run方法,编写线程执行体
  3. 创建线程对象,调用start()方法启动线程
package com.kuang.demo01;

//创建线程方式一:继承Thread,重写run方法,调用start方法
public class TestThread1 extends Thread {
    @Override
    public void run() {
        //run方法线程体
//        快速写循环20.for
        for (int i = 0; i < 20; i++) {
            System.out.println("我在看代码----------"+i);
        }

    }

    public static void main(String[] args) {
        //main线程,主线程

        //创建一个线程对象,调用start方法开启线程
        TestThread1 testThread1 =new TestThread1();
        testThread1.start();

    /*        testThread1.run();
            当调用run方法时,先走run方法,而start方法时开启本线程,可以交替执行
            
     */

        for (int i = 200; i > 0; i--) {
            System.out.println("我在学习多线程+-------"+i);
        }

    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kG2jmaHi-1651654409853)(${images}/image-20210514113108405.png)]

总结:线程开辟不一定立即执行,由cpu调度执行

小栗子1.多线程下载图片

package com.kuang.demo01;

import org.apache.commons.io.FileUtils;

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

//ctrl+d直接复制
public class TestThread02  extends  Thread{
    //2.设置成员变量
   private String url;
    private String filename;
    //3.初始化构造方法
    public TestThread02(String url,String filename){
        this.url=url;
        this.filename=filename;
    }
    //4.重写run方法
    @Override
    public void run() {
        WebDownload webDownload=new WebDownload();
        webDownload.download(url,filename);
        System.out.println("下载的文件名为:"+filename);
    }

    public static void main(String[] args) {
        TestThread02 testThread1=new TestThread02("https://img0.baidu.com/it/u=2124865496,798253780&fm=11&fmt=auto&gp=0.jpg","1.jpg");
        TestThread02 testThread2=new TestThread02("https://img1.baidu.com/it/u=1980119653,2367229126&fm=11&fmt=auto&gp=0.jpg","2.jpg");
        TestThread02 testThread3=new TestThread02("https://img0.baidu.com/it/u=4087748813,965176217&fm=11&fmt=auto&gp=0.jpg","3.jpg");

        testThread1.start();
        testThread2.start();
        testThread3.start();

    }
}


//1.创建一个下载器
class WebDownload{
    //下载方法
    public void download(String  url,String filename){
        try {
            FileUtils.copyURLToFile(new URL(url),new File(filename));
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("io异常,download方法出现问题");
        }
    }

        }

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FvNZ6Vfp-1651654409854)(${images}/image-20210514125808960.png)]

◆继承Thread类
◆子类继承Thread类具备多线程能力
◆启动线程:子类对象.start(0
◆不建议使用:避免OOP单继承局限性

3.2 runable接口实现
package com.kuang.demo01;
//创建线程方法2:思想runable接口,重写run方法,执行线程
public class TestTread03 implements Runnable {

    @Override
    public void run() {
        for (int i = 0; i < 20; i++) {
            System.out.println("我在看代码----------"+i);
        }
    }

    public static void main(String[] args) {
        //创建runable接口实现类对象
        TestTread03 testTread03 = new TestTread03();
        new Thread(testTread03).start();
        for (int i = 200; i > 0; i--) {
            System.out.println("我在学习多线程+-------"+i);
        }
    }
}

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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-g95nQQDA-1651654409854)(java多线程Img/image-20220316201744388.png)]

初始多并发

package com.kuang.demo01;

public class TestThread04 implements Runnable{
private int tickNum=10;
    @Override
    public void run() {
        while (true){
            if (tickNum<=0){
                break;
            }

            try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName()+"-->拿到了第"+tickNum--+"票");
        }
    }

    public static void main(String[] args) {
        TestThread04 ticket = new TestThread04();
        new Thread(ticket,"小明").start();
        new Thread(ticket,"小红").start();
        new Thread(ticket,"黄牛").start();

    }
}
3.3实现Callable接口(了解即可)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LkSnyE2k-1651654409854)(java多线程Img/image-20220316214506265.png)]

package com.kuang.demo02;

import com.kuang.demo01.TestThread02;
import org.apache.commons.io.FileUtils;

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.concurrent.*;

/*
1、可以定义返回值
2、可以抛出异常
 */
public class TestCallable  implements Callable<Boolean> {
    //2.设置成员变量
    private String url;
    private String filename;
    //3.初始化构造方法
    public TestCallable(String url,String filename){
        this.url=url;
        this.filename=filename;
    }
    //4.重写run方法
    @Override
    public Boolean call() {
        WebDownload webDownload=new WebDownload();
        webDownload.download(url,filename);
        System.out.println("下载的文件名为:"+filename);
        return true;
    }

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        TestCallable testThread1=new TestCallable("https://img0.baidu.com/it/u=2124865496,798253780&fm=11&fmt=auto&gp=0.jpg","1.jpg");
        TestCallable testThread2=new TestCallable("https://img1.baidu.com/it/u=1980119653,2367229126&fm=11&fmt=auto&gp=0.jpg","2.jpg");
        TestCallable testThread3=new TestCallable("https://img0.baidu.com/it/u=4087748813,965176217&fm=11&fmt=auto&gp=0.jpg","3.jpg");

        //创建执行服务
        ExecutorService ser = Executors.newFixedThreadPool(3);

        //提交执行
        Future<Boolean> submit1 = ser.submit(testThread1);
        Future<Boolean> submit2= ser.submit(testThread2);
        Future<Boolean> submit3 = ser.submit(testThread3);

        //获取结果
        Boolean res1 = submit1.get();
        Boolean res2 = submit2.get();
        Boolean res3 = submit3.get();

        //关闭服务
        ser.shutdown();

    }
}
//1.创建一个下载器
class WebDownload{
    //下载方法
    public void download(String  url,String filename){
        try {
            FileUtils.copyURLToFile(new URL(url),new File(filename));
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("io异常,download方法出现问题");
        }
    }

}

ass WebDownload{
//下载方法
public void download(String url,String filename){
try {
FileUtils.copyURLToFile(new URL(url),new File(filename));
} catch (IOException e) {
e.printStackTrace();
System.out.println(“io异常,download方法出现问题”);
}
}

}

>未完待续
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

奥丁之眼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值