目录

多线程

进程和线程

进程介绍

并行和并发

进程介绍

多进程同时执行

线程介绍

多线程的意义

Java 开启线程的方式

线程相关方法

线程调度方式

​编辑

线程安全和同步

线程安全问题分析

线程同步

线程池介绍

线程池学习路径

自定义线程​编辑

线程池拒绝策略


多线程

进程和线程

进程介绍

进程 (Process) 是计算机中的程序关于某数据集合上的一次运行活动
是系统进行资源分配的基本单位

简单理解:程序的执行过程

独立性:每一个进程都有自己的空间,在没有经过进程本身允许的情况下,一个进程不可以直接访问其它的的进程空间
动态性:进程是动态产生,动态消亡的
并发性:任何进程都可以同其它进程一起并发执行

并行和并发

并行:在同一时刻,有多个指令在多个CPU上【同时】执行 

并发:在同一时刻,有多个指令在单个CPU上【交替】执行

进程介绍

多进程同时执行

多进程同时执行

进程(Process):程序的执行过程
独立性:
    每一个进程都有自己的空间,在没有经过进程本身允许的
    情况下,一个进程不可以直接访问其它的的进程空间
动态性:进程是动态产生,动态消亡的
并发性:任何进程都可以同其它进程一起并发执行
多进程同时工作
    对于一个 CPU 而言,它是在多个进程间轮换执行的

线程介绍

线程 (Thread) : 进程可以同时执行多个任务,每个任务就是线程

多线程的意义

随着处理器上的核心数量越来越多,现在大多数计算机都比以往更加擅长并行计算

一个线程,在一个时刻,只能运行在一个处理器核心上

线程:进程中的任务,多线程就是多个任务
多线程的意义:
    提高效率
    可以同时处理多个任务

Java 开启线程的方式

package com.itheima.thread;

public class ThreadDemo01 {
    public static void main(String[] args) {
        //创建线程对象
        Mythread mythread = new Mythread();
        //调用start使用线程
        mythread.start();
        for (int i = 0; i < 100; i++) {
            System.out.println("主线程执行的次数"+i);
        }
    }

}
//编写一个类继承Thread
class Mythread extends Thread{
    //重写run方法
    @Override
    //将线程任务代码写在run方法当中
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println("子线程执行的次数"+i);
        }
    }
}
package com.itheima.thread;

public class ThreadDemo02 {
    /*
    开启线程的第二种方式  实现Runnable接口
    1,编写一个类方法实现runnable
    2.重写run方法
    3.将线程任务代码 写在run方法当中
    4.创建Runnable接口的实现类对象
    5.创建线程对象并将Ruuable接口的实现类闯入
    6.使用线程对象调用start方法开启线程
     */
    public static void main(String[] args) {
        MyThread1 mythread = new MyThread1();
        Thread t1 = new Thread(mythread);
        t1.start();
        for (int i = 0; i < 10; i++) {
            System.out.println("线程"+i);
        }
    }
}
class MyThread1 implements Runnable {

    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            System.out.println("自己的线程"+i);
        }
    }
}
package com.itheima.thread;

import java.util.concurrent.Callable;

//编写一个类实现Callable接口
public class Thead5 implements Callable<Integer> {
    //重写call方法(此方法存在返回值)
    @Override
    public Integer call() throws Exception {
        int sum = 0;
        for (int i = 0; i < 100; i++) {
            sum += i;
        }
        return sum;
    }
}

线程相关方法

方法名称

说明

String getName​()

返回此线程的名称

void setName​(String name)

设置线程的名字(构造方法也可以设置名字)

static Thread currentThread()

获取当前线程的对象

static void sleep(long time)

让线程休眠指定的时间,单位为毫秒

setPriority(int newPriority)

设置线程的优先级

final int getPriority()

获取线程的优先级

final void setDaemon(boolean on)

设置为守护线程

方法名称

说明

String getName​()

返回此线程的名称

void setName​(String name)

设置线程的名字(构造方法也可以设置名字)

static Thread currentThread()

获取当前线程的对象

static void sleep(long time)

让线程休眠指定的时间,单位为毫秒

方法名称

说明

setPriority(int newPriority)

设置线程的优先级

final int getPriority()

获取线程的优先级

线程调度方式

方法名称

说明

String getName​()

返回此线程的名称

void setName​(String name)

设置线程的名字(构造方法也可以设置名字)

static Thread currentThread()

获取当前线程的对象

static void sleep(long time)

让线程休眠指定的时间,单位为毫秒

setPriority(int newPriority)

设置线程的优先级

final int getPriority()

获取线程的优先级

final void setDaemon(boolean on)

设置为守护线程

线程安全和同步

需求:
某电影院目前正在上映国产大片,共有100张票,而它有3个窗口卖票
请设计一个程序模拟该电影院卖票

package com.itheima.test;

import java.util.concurrent.locks.ReentrantLock;

public class ThreadTest3 {
    public static void main(String[] args) {
        TicketTask3 ticket = new TicketTask3();
        Thread t1 = new Thread(ticket,"窗口A");
        Thread t2 = new Thread(ticket,"窗口B");

        t1.start();
        t2.start();

    }
}
class TicketTask3 implements Runnable {
    int tickets=1000;
    ReentrantLock lock = new ReentrantLock();
    @Override
    public void run() {

        while(true){
            try {
                lock.lock();
                if(tickets==0){
                    break;
                }
                System.out.println(Thread.currentThread().getName()+"卖出了第"+tickets+"号票");
                tickets--;
                lock.unlock();
            } finally {
                lock.unlock();
            }
        }
    }
}

安全问题出现的条件
    是多线程环境
    有共享数据
    有多条语句操作共享数据

线程安全问题分析

线程同步

线程池介绍

系统创建一个线程的成本是比较高的,因为它涉及到与操作系统交互

当程序中需要创建大量生存期很短暂的线程时,频繁的创建和销毁线程,就会严重浪费系统资源

线程池学习路径

Executors 中提供静态方法来创建线程池

方法

介绍

static ExecutorService newCachedThreadPool ()

创建一个默认的线程池

static newFixedThreadPool (int nThreads)

创建一个指定最多线程数量的线程池 

自定义线程

线程池拒绝策略

策略选项

说明

ThreadPoolExecutor.AbortPolicy 

丢弃任务并抛出RejectedExecutionException异常 (默认)

ThreadPoolExecutor.DiscardPolicy

丢弃任务,但是不抛出异常 这是不推荐的做法

ThreadPoolExecutor.DiscardOldestPolicy

抛弃队列中等待最久的任务 然后把当前任务加入队列中

ThreadPoolExecutor.CallerRunsPolicy

调用任务的run()方法绕过线程池直接执行

临时线程什么时候创建? 
线程任务数 > 核心线程数 + 任务队列的数量
什么时候会开启拒绝策略
线程任务数 > 最大线程数 + 任务队列的数量

package com.itheima.threadpool;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class TheadDemo02 {
    public static void main(String[] args) {
        ThreadPoolExecutor pool = new ThreadPoolExecutor(
                2,
                3,
                60,
                TimeUnit.SECONDS,
                new ArrayBlockingQueue<Runnable>(10),
                Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.AbortPolicy()
        );
        for (int i = 0; i < 16; i++) {
            pool.submit(new Runnable() {
                @Override
                public void run() {
                    System.out.println(Thread.currentThread().getName()+"--提交了任务");
                }
            });
        }
    }
}

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐