day13-线程

线程

普通任务和多线程任务的区别
在这里插入图片描述

程序,进程线程的区别

在操作系统中运行的程序就是进程,一个进程可以有多个线程。

  • 程序是指令和数据的有序集合,其本身没有任何运行的含义,是一个静态的概念。
  • 进程是执行程序的一次执行过程,他是一个动态的概念。是系统资源分配的单位
  • 通常一个进程中可以包含若干个线程,当然一个进程中至少有一个线程,不然没有存在的意义,线程是CPU调度和执行的单位。

注意:很多多线程是模拟出来的,真正的多线程是指有多个CPU,即多核,如服务器。如果是模拟出来的多线程,即在一个CPU的情况下,在同一时间点,CPU只能执行一个代码,因为切换的很快,所以就有同时执行的错觉。

总结:

  • 线程就是独立执行路径
  • java会调用多核来实现多线程,这就是和python的区别
  • 程序运行时,即使没有自己创建线程,后台也会有多个线程,如主线程从,gc线程。
  • main()称之为主线程,为系统的入口,用于执行整个程序‘
  • 在一个进程中,如果开辟了多个线程,线程的运行由调度器安排调度,调度器是与操作系统紧密相关的,先后顺序是不能认为的干预
  • 对同一份资源操作时,会存在资源抢夺的问题,需要加入并发控制;
  • 线程会带来额外的开销,如cpu调度时间,并发控制开销
  • 每个线程在自己的工作内存交互,内存 控制不当会造成数据不一致

创建方式

Tread class 继承Thread类

打开jdk帮助文档查看Thread

我们可以知道Thread实现了Runnable接口

A thread is a thread of execution in a program. The Java Virtual Machine allows an application to have multiple threads of execution running concurrently.
Every thread has a priority. Threads with higher priority are executed in preference to threads with lower priority. Each thread may or may not also be marked as a daemon. When code running in some thread creates a new Thread object, the new thread has its priority initially set equal to the priority of the creating thread, and is a daemon thread if and only if the creating thread is a daemon.

When a Java Virtual Machine starts up, there is usually a single non-daemon thread (which typically calls the method named main of some designated class). The Java Virtual Machine continues to execute threads until either of the following occurs:

  • The exit method of class Runtime has been called and the security manager has permitted the exit operation to take place.
  • All threads that are not daemon threads have died, either by returning from the call to the run method or by throwing an exception that propagates beyond the run method.

当Java虚拟机启动时,通常有一个非守护进程线程(通常调用某些指定类的名为main的方法)。 Java虚拟机将继续执行线程,直到发生以下任一情况:

  • 已经调用了Runtime类的exit方法,并且安全管理器已经允许进行退出操作。
  • 所有不是守护进程线程的线程都已经死亡,无论是从对run方法的调用返回还是抛出传播超出这个run方法的异常。

上面的就是原版文档,需要对英语稍微好一点,不过也别急,可以慢慢学。扩充知识。重点部分我会在下方贴上翻译

如果过于吃力,可以对照中文文档学习,这个中文文档是谷歌翻译出来的,可能还是有小问题。
https://www.matools.com/api/java8

总的来说,归为以下几个步骤

  • 自定义线程类继承Thread类
  • 重写run()方法,编写线程执行体
  • 创建线程对象,调用start()方法启动线程

简单一个例子

//创建线程方式一:继承Thread类,重写run方法,调用start开启线程
public class Thread1 extends Thread{
    @Override
    public void run(){//run方法主体
        for (int i = 0; i < 10; i++) {
            System.out.println("Thread1线程--"+i);
        }
    }

    public static void main(String[] args) {
        //main线程,主线程
        Thread1 thread1 = new Thread1();//创建线程对象,
        thread1.start();//调用start开启线程
        for (int i = 0; i < 10; i++) {
            System.out.println("main线程--"+i);
        }
    }
}

结果应该是交替

main线程--0
Thread1线程--0
main线程--1
main线程--2

不过每次都可能不一样。如果遇见没有交替的情况就可以多试试。线程开启后不一定立即执行,线程具体如何就看CPU怎么调度了。

简单例子例子

package testThread;

import org.apache.commons.io.FileUtils;

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

//继承Thread,实现多线程同步下载图片
public class testThread2 extends Thread{

    private String URL;//网络图片地址
    private String name;//保存的文件名
    public testThread2(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) {
        testThread2 t0 = new testThread2("https://i2.hdslb.com/bfs/face/83bb511365da513c55aa3d1958524f3b7db40684.jpg@64w_64h.webp","0.jpg");
        testThread2 t1 = new testThread2("https://i2.hdslb.com/bfs/archive/0ae34a0c6347a0fd2ccc7f7f468d551ae4439326.jpg@336w_190h.webp","1.jpg");
        testThread2 t2 = new testThread2("https://i0.hdslb.com/bfs/archive/756f7695bcdd43e45bf2313a01b9194bc637d788.jpg@336w_190h.webp","2.jpg");
        t0.start();
        t1.start();
        t2.start();
    }
}

//下载器
class WebDownloader {
    //下载方法
    public void downloader(String url,String name){
        try {
            FileUtils.copyURLToFile(new URL(url),new File(name));//org.apache.commons.io.FileUtils类,将一个url复制为文件,需要自行下载后拷贝到依赖中
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("IO异常,downloader出现问题");
        }
    }
}
下载的文件名为1.jpg
下载的文件名为0.jpg
下载的文件名为2.jpg

逻辑思路:
就是设置一个下载器,再将testThread2继承Thread后实现run()方法。在main中new出来3个线程后再start

Runnable 实现Runnable接口
  • 定义MyRunnable类实现Runnable接口
  • 实现run()方法,编写线程执行体
  • 创建线程对象,调用start()方法启动线程

例子

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

    public static void main(String[] args) {
        //main线程,主线程
        //创建runnable接口的实现类对象
        TestThread3 testThread3 = new TestThread3();

        //创建线程对象,通过线程对象来开启我们的线程,代理
        new Thread(testThread3).start();

        for (int i = 0; i < 10; i++) {
            System.out.println("main线程--"+i);
        }
    }
}

其中构造函数Thread(),指明了要添加一个Runnable 类作为参数。

    /**
     * Allocates a new {@code Thread} object. This constructor has the same
     * effect as {@linkplain #Thread(ThreadGroup,Runnable,String) Thread}
     * {@code (null, target, gname)}, where {@code gname} is a newly generated
     * name. Automatically generated names are of the form
     * {@code "Thread-"+}<i>n</i>, where <i>n</i> is an integer.
     *
     * @param  target
     *         the object whose {@code run} method is invoked when this thread
     *         is started. If {@code null}, this classes {@code run} method does
     *         nothing.
     */
    public Thread(Runnable target) {
        init(null, target, "Thread-" + nextThreadNum(), 0);
    }

小结:

继承Thread类

  • 子类继承Thread类具有多线程能力
  • 启动线程:子类对象.start()
  • 不建议使用:便面oop单继承局限性

实现RUnnable接口

  • 实现接口Runnable具有多线程能力
  • 启动线程:(传入目标对象+Thread对象).start()
  • 推荐使用:避免单继承局限性,灵活方便,方便同一个对象被多个线程使用
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值