Java线程

1.什么是进程?

  进行运行的程序叫做进程,进程是系统分配资源的基本单位,使用PID来区别进程

2.什么是线程?

线程是进程中的一条执行路径,也是CPU的基本调度单位。一个进程有一个或多个线程组成,彼此间完成不同的工作,同时执行,称为多线程。

3.进程和线程的区别

    (1)进程是操作系统资源分配的基本单位,而线程是CPU的基本调度单位。

    (2)一个程序运行后至少有一个进程

    (3)一个进程可以包含多个线程,但是只有需要有一个线程,否则这个进程是没有意义。

    (4)进程间不能共享数据段地址,但是同进程的线程之间可以。

4.为什么使用线程

为了解决负载均衡问题,充分利用CPU资源,为了提高CPU的使用率,采用多线程的方式去同时完成几件事情而互不干扰,为了处理大量的IO操作时或处理的情况需要花费大量的时间等等,比如:读写文件,视频图像 的采集,处理,显示,保存等

单核时代: 在单核时代多线程主要是为了提高 CPU 和 IO 设备的综合利用率。举个例子:当只有一个 线程的时候会导致 CPU 计算时,IO 设备空闲;进行 IO 操作时,CPU 空闲。我们可以简单地说这两者 的利用率目前都是 50%左右。但是当有两个线程的时候就不一样了,当一个线程执行 CPU 计算时,另外 一个线程可以进行 IO 操作,这样两个的利用率就可以在理想情况下达到 100%了。

多核时代: 多核时代多线程主要是为了提高 CPU 利用率。举个例子:假如我们要计算一个复杂的任务, 我们只用一个线程的话,CPU 只会一个 CPU 核心被利用到,而创建多个线程就可以让多个 CPU 核心被 利用到,这样就提高了 CPU 的利用率

5.Java如何创建线程

方式一:继承Thread类:

package com.zzx.线程;

/**
 * @date: 2022/08/10/ 22:24
 * @author: ZhengZiXuan
 * @title: 通过继承Thread类来实现线程,调用run/start方法
 * @description:
 */
public class ThreadTest extends Thread{ //此处按住Ctrl+鼠标左键点击进入源码,发现Thread类实现了Runnable接口(如图一所示)
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println("我在听课"+i);
        }
    }
}

class Test{
    public static void main(String[] args) {
        ThreadTest threadTest = new ThreadTest();
        threadTest.start();
        for (int i = 0; i < 2000; i++) {
            System.out.println("我在看代码"+i);

        }

    }
}

在这里插入图片描述
运行start方法,控制台打印结果:
在这里插入图片描述

通过控制台运行结果可看出,当调用start方法时,两条线程是同时执行的

package com.zzx.线程;

/**
 * @date: 2022/08/10/ 22:24
 * @author: ZhengZiXuan
 * @title: 通过继承Thread类来实现线程,调用run/start方法
 * @description:
 */
public class ThreadTest extends Thread{
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println("我在听课"+i);
        }
    }
}

class Test{
    public static void main(String[] args) {
        ThreadTest threadTest = new ThreadTest();
        threadTest.run();
        for (int i = 0; i < 2000; i++) {
            System.out.println("我在看代码"+i);

        }

    }
}


// 总结: 线程开启不一定立即执行,由CPU调度执行


当调用run方法时,我们可以发现两个线程是顺序执行的,也就是第一条线程执行完之后,第二条线程才会执行,以此类推

在这里插入图片描述
附带:Thread小练习(网图下载)

方式二: 实现Runnable接口

package com.zzx.线程.Runnable;

/**
 * @date: 2022/08/15/ 22:13
 * @author: ZhengZiXuan
 * @title:
 * @description: 实现Runnable接口,重写run方法,执行线程需要丢入Runnable接口实现类,调用start方法
 */
public class RunnableTest implements Runnable{

    public void run() {
        for (int i = 0; i < 1000; i++) {
            System.out.println("我正在学习Runnable,第: " + i + " 次~~~");
        }
    }
}

class Test{
    public static void main(String[] args) {
        //创建Runnable接口的实现类对象
        RunnableTest runnableTest = new RunnableTest();
        //创建线程对象,通过线程对象来开启我们的线程,代理
        Thread thread = new Thread(runnableTest); //此处按住Ctrl+鼠标左键点击进入,查看其构造器(如图一所示)发现参数需要一个目标的Runnable接口
        thread.start();
        for (int i = 0; i < 1000; i++) {
            System.out.println("魏武遗风: "+ i + " 曹操~~~");

        }
        //runnableTest.run();
    }
}

在这里插入图片描述
运行start方法,控制台打印结果:
在这里插入图片描述
通过运行我们发现,当调用run方法时,线程是同时执行的
Runnable小练习(网图下载)

方式三: 实现Callable接口:

package com.zzx.线程.Callable;


import org.apache.commons.io.FileUtils;

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

/**
 * @date: 2022/08/17/ 22:02
 * @author: ZhengZiXuan
 * @title: 方式三: 实现callable接口
 * @description:
 */
public class CallableTest implements Callable<Boolean> {

    //网络图片地址
    private String url;

    //保存的文件名
    private String name;


    public Boolean call() {
        WebDownloader webDownloader = new WebDownloader();
        webDownloader.downLoader(url,name);
        System.out.println("下载了文件名为:"+name);
        return true;
    }

    public CallableTest(String url,String name) {
        this.name=name;
        this.url = url;
    }

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        CallableTest c1 = new CallableTest("https://nimg.ws.126.net/?url=http%3A%2F%2Fdingyue.ws.126.net%2F2021%2F0731%2Fe91198a9j00qx35q30050c000j600nym.jpg&thumbnail=660x2147483647&quality=80&type=jpg","小姐姐1.jpg");
        CallableTest c2 = new CallableTest("https://nimg.ws.126.net/?url=http%3A%2F%2Fdingyue.ws.126.net%2F2020%2F0308%2Faa2f8437j00q6uv1c001fc000hs00hsm.jpg&thumbnail=660x2147483647&quality=80&type=jpg","小姐姐2.jpg");
        CallableTest c3 = new CallableTest("https://nimg.ws.126.net/?url=http%3A%2F%2Fdingyue.ws.126.net%2F2020%2F0308%2F94d8bda3j00q6uv1e000oc000hs00m7m.jpg&thumbnail=660x2147483647&quality=80&type=jpg","小姐姐3.jpg");

        //创建执行服务
        ExecutorService executorService = Executors.newFixedThreadPool(3); //创建三个线程

        //提交执行
        Future<Boolean> result1 = executorService.submit(c1);
        Future<Boolean> result2 = executorService.submit(c2);
        Future<Boolean> result3 = executorService.submit(c3);

        //获取结果
        boolean b1 = result1.get();
        boolean b2 = result2.get();
        boolean b3 = result3.get();
        System.out.println("b1:"+ b1);
        System.out.println("b2:"+ b2);
        System.out.println("b3:"+ b3);


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

    }
}
//下载器
class WebDownloader{
    //下载方法
    public void downLoader(String pictureUrl, String name){
        try {
            FileUtils.copyURLToFile(new URL(pictureUrl),new File(name));
        } catch (IOException e) {
            e.printStackTrace();
            System.err.println("IO异常,downloader方法出现问题");
        }
    }
}

在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

小郑要做干饭人

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

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

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

打赏作者

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

抵扣说明:

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

余额充值