Java基础2.5-多线程

目录

多线程

进程和线程

进程介绍

并行和并发

进程介绍

多进程同时执行

线程介绍

多线程的意义

[Java 开启线程的方式](#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()+"--提交了任务");
                }
            });
        }
    }
}
相关推荐
a35354138211 小时前
设计模式-原型模式
开发语言·c++
不知疲倦的仄仄11 小时前
第一天:从 ByteBuffer 内存模型到网络粘包处理实战
java·网络·nio
Tinachen8811 小时前
YonBIP旗舰版本地开发环境搭建教程
java·开发语言·oracle·eclipse·前端框架
liulilittle11 小时前
libxdp: No bpffs found at /sys/fs/bpf
linux·运维·服务器·开发语言·c++
hqwest11 小时前
码上通QT实战07--主窗体消息栏设计
开发语言·qt·qt事件·主窗体·stackedwidget
hqwest11 小时前
码上通QT实战06--导航按钮事件
开发语言·qt·mousepressevent·qfont·qpainter·qlineargradient·setbrush
星火开发设计11 小时前
堆排序原理与C++实现详解
java·数据结构·c++·学习·算法·排序算法
shughui12 小时前
实现Python多版本共存
开发语言·python·pip
dhdjjsjs12 小时前
Day58 PythonStudy
开发语言·python·机器学习
七七powerful12 小时前
docker28.1.1和docker-compose v.2.35.1安装
java·docker·eureka