java之多线程篇

一、基本概念

1.什么是线程?

线程就是,操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。简单理解就是:应用软件中互相独立,可以同时运行的功能

2.什么是多线程?

有了多线程,我们就可以让程序同时做多件事情

3.多线程的作用?

提高效率

4.线程的应用场景?

只要你想让多个事情同时运行就需要用到多线程

比如:软件中的耗时操作、所有的聊天软件、所有的服务器

二、并发和并行的概念

1.什么是并发?

并发就是,同一时刻,有多个指令在单个CPU上交替执行。

2.什么是并行?

并行就是,同一时刻,有多个指令在多个CPU上同时执行

3.电脑不是只有一个CPU么,这个多个CPU同时执行的并行究竟是什么?

其实,CPU在市面有很多类型如下

比如2核4线程的CPU,就可以同时运行4个线程的任务。

三、多线程的实现方式(3种) 

1.继承Thread类的方式进行实现

用法:

1.定义一个类继承Thread类

2.这个类重写run方法

3.在main方法里面创建定义的类的对象

4.通过该对象的.start()方法启动线程

示例代码

public class ThreadDemo1 {
    public static void main(String[] args) {
        MyThread myThread1 = new MyThread();
        MyThread myThread2 = new MyThread();
        myThread1.setName("线程1");
        myThread2.setName("线程2");
        myThread1.start();
        myThread2.start();
    }
}
class MyThread extends Thread{
    @Override
    public void run(){
        for(int i=0;i<100;i++){
            System.out.println(Thread.currentThread().getName()+" "+i);
        }
    }
}

上面的两个线程的代码run方法是同时执行的,并不会等一个线程的循环走完。

注意:线程类开启后执行的是run方法的代码 

2.实现Runnable接口的方式进行实现

用法:

1.自己定义一个类实现Runnable接口

2.重写里面的run方法

3.在main方法创建自己的类的对象

4.将定义的类传递给Thread构造方法创建一个Thread类的对象,并开启线程

示例 

public class ThreadDemo2 {
    public static void main(String[] args) {
        MyThread myThread = new MyThread();
        Thread thread1 = new Thread(myThread);
        Thread thread2 = new Thread(myThread);
        thread1.setName("线程1");
        thread2.setName("线程2");
        thread2.start();
        thread1.start();
    }
}
class MyThread implements Runnable{
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println(Thread.currentThread().getName()+"-->"+i);
        }
    }
}

3.利用Callable接口和Future接口方式实现

前面两种实现方式,run方法没有返回值,不知道线程实现的结果,现在这个第三种方法是有返回值的。

用法:

1.创建一个类MyCallable实现callable接口

2.重写call(是有返回值的,表示多线程运行的结果)

3.创建MyCallable的对象(表示多线程要执行的任务)

4.传递MyCallable对象为参数创建FutureTask的对象(作用管理多线程运行的结果)

5.传递FutureTask对象为参数创建Thread类的对象,并启动(表示线程)

 示例

public class ThreadDemo3 {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        MyCallable mc = new MyCallable();
        FutureTask<Integer> ft = new FutureTask<>(mc);
        Thread t = new Thread(ft);
        t.start();
        System.out.println(ft.get());
    }
}
class MyCallable implements Callable<Integer> {
    @Override
    public Integer call() throws Exception {
        int sum = 0;
        for (int i = 0; i <= 100; i++) {
            sum += i;
        }
        return sum;
    }
}

结果输出5050

4.三种方式的比较 

四、Thread类的常用成员方法

1.七个方法

2.前四个细节

String getName()

void setName(String name)

细节:

        1. 果我们没有给线程设置名字,线程也是有默认的名字的

                格式:Thread-X(X序号,从0开始的)

        2.如果我们要给线程设置名字,可以用set方法进行设置,也可以构造方法设置

static Thread currentThread()

细节:

        当JVM虚拟机启动之后,会自动的启动多条线程

        其中有一条线程就叫做main线程

        他的作用就是去调用main方法,并执行里面的代码

        在以前,我们写的所有的代码,其实都是运行在main线程当中

static void sleep(long time)   

细节:

        1.哪条线程执行到这个方法,那么哪条线程就会在这里停留对应的时间

        2.方法的参数:就表示睡眠的时间,单位毫秒

                1秒 = 1000毫秒

        3.时间到了之后,线程会自动的醒来,继续执行下面的其他代码

 3.线程的优先级

(1)线程调度

抢占式调度:各条线程执行的顺序和时间是不确定的(随机)

非抢占式调度:各条线程执行的顺序是轮流执行和执行时间是差不多的

java中是选取第一种抢占式调度

(2)优先级(1~10)

抢占式调度就要涉及到线程的优先级越大,执行的顺序越前

于是可以通过Thread类的上面的两个成员方法来设置和获取线程的优先级

没有设置默认就是5

注意:这里的优先级是指优先级大的线程先执行的概率比较大,而不是百分百,比如说有两个一样的方法的线程,优先大的线程是有概率计较大的先执行完,但还是有小概率执行慢

 4.守护线程

当一个线程使用Thread类的etDaemon(boolean on)时,这个线程变成守护线程。

细节:

这个线程也可以叫做“备胎”线程,它将其他线程视为“女神”线程,当其他线程结束的时候,这个守护线程就会陆续结束,觉得自己没必要存在了,这就会可能导致守护线程的代码没有全部执行完。

应用场景

 上面聊天的场景,两个人聊天开两个线程,一个聊天,一个传输文件,如果聊天线程关闭了,就没有传输文件的必要了,于是将传输文件的线程设置为守护线程。

 5.出让/礼让线程

在当前线程的工作不重要时,将CPU资源让位给其他线程,通过使用Thread类的yield()方法来将当前资源让位给其他同优先级线程

publ
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值