Java 多线程(抢CPU)

哈哈哈

什么是多线程:可以让程序同时做多件事情。

多线程的作用:提高效率。

多线程的应用场景:想让多个事情同时运行。

 并发(多个指令在单个CPU交替执行)和并行(多个指令在多个CPU交替执行)

多线程的实现方式:

1.继承Thread类的方式实现(简单,扩展性差)

public class ss {
    public static void main(String[] args) {
        //1.自己定义一个类继承Thread
        //2.重写run方法
        //3.创建子类的对象,并启动线程
        MyThread t1=new MyThread();
        MyThread t2=new MyThread();

        t1.setName("1");
        t2.setName("2");

        t1.start();
        t2.start();
    }
}
public class MyThread extends Thread{
    @Override
    public void run(){
        for (int i = 0; i < 100; i++) {
            System.out.println(getName()+"hello");
        }
    }
}

2.实现Runnable接口的方式进行实现(复杂,扩展性强)

public class ss {
    public static void main(String[] args) {
        //1.自己定义一个类实现Runnable接口
        //2.重写里面的run方法
        //3.创建自己的类的对象
        //4.创建一个Thread类的对象,并开启线程
        MyRun mr=new MyRun();

        Thread t=new Thread(mr);
        Thread t2=new Thread(mr);

        t.setName("1");
        t2.setName("2");

        t.start();
        t2.start();
    }
}
public class MyRun implements Runnable{
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            Thread t=Thread.currentThread();
            System.out.println(t.getName()+"hello");
        }
    }
}

3.利用Callable接口和Future接口方式实现(可以获取结果)

import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;

public class ss {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        //1.创建一个类MyCallable实现Callable接口
        //2.重写call
        //3.创建MyCallable对象
        //4.创建FutureTask的对象
        //5.创建Thread类对象并启动
        MyCallable mc=new MyCallable();

        FutureTask<Integer> ft=new FutureTask<>(mc);

        Thread t1=new Thread(ft);

        t1.start();

        Integer result=ft.get();
        System.out.println(result);

    }
}
import java.util.concurrent.Callable;

public class MyCallable implements Callable<Integer>{
    @Override
    public Integer call() throws Exception{
        int sum=0;
        for (int i = 0; i < 100; i++) {
            sum=sum+i;
        }
        return sum;
    }

}

多线程的常用成员方法

public class ss {
    public static void main(String[] args) throws InterruptedException {
        //getName
        MyThread mt=new MyThread("111");
        MyThread t2=new MyThread();

        mt.start();
        t2.start();
        //setName
        //....

        //currentThread
        Thread t=Thread.currentThread();
        System.out.println(t.getName());

        //sleep(long time)毫秒 睡眠时间
        System.out.println("11111");
        Thread.sleep(5000);
        System.out.println("22222");

    }
}
public class MyThread extends Thread{
    public MyThread() {
    }

    public MyThread(String name) {
        super(name);
    }

    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            System.out.println(getName()+"@"+i);
        }
    }
}

线程的优先级

public class ss {
    public static void main(String[] args) throws InterruptedException {
        MyRunnable mr=new MyRunnable();

        Thread t1=new Thread(mr,"1");
        Thread t2=new Thread(mr,"2");

        System.out.println(t1.getPriority());//默认优先级5
        System.out.println(t2.getPriority());//默认优先级5//最小1//最大10

        t1.setPriority(1);
        t2.setPriority(10);

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

    }
}
public class MyRunnable implements Runnable{
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println(Thread.currentThread().getName()+"@"+i);

        }
    }
}

守护线程(起码有2个线程)

public class ss {
    public static void main(String[] args) throws InterruptedException {
        MyThread t1=new MyThread();
        MyThread2 t2=new MyThread2();

        t1.setName("1");
        t2.setName("2");

        t2.setDaemon(true);

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

    }
}
public class MyThread extends Thread{

    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            System.out.println(getName()+"@"+i);
        }
    }
}
public class MyThread2 extends Thread{

    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            System.out.println(getName()+"@"+i);
        }
    }
}

礼让线程

public class ss {
    public static void main(String[] args) throws InterruptedException {
        MyThread2 t1=new MyThread2();
        MyThread2 t2=new MyThread2();

        t1.setName("1");
        t2.setName("2");

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

    }
}
public class MyThread2 extends Thread{

    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println(getName()+"@"+i);
            Thread.yield();//礼让一下,再重新抢夺CPU的执行权
        }
    }
}

插入线程/插队线程

public class ss {
    public static void main(String[] args) throws InterruptedException {
        MyThread t1=new MyThread();
        t1.setName("1");
        t1.start();
        
        t1.join();//把t线程插入到当前线程(main)之前

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

    }
}
public class MyThread extends Thread{

    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println(getName()+"@"+i);
        }
    }
}

线程的生命周期:

一个线程从创建,到结束。

线程的安全问题

(下面这个代码存在问题)

public class ss {
    public static void main(String[] args) throws InterruptedException {
        MyThread t1=new MyThread();
        MyThread t2=new MyThread();
        MyThread t3=new MyThread();

        t1.setName("窗口1");
        t2.setName("窗口2");
        t3.setName("窗口3");

        t1.start();
        t2.start();
        t3.start();
    }
}
public class MyThread extends Thread{

    static int ticket=0;//这个类所有对象共享ticket数据(加了static)
    @Override
    public void run() {
        while (true){
            if(ticket<100){
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                ticket++;
                System.out.println(getName()+"正在卖第"+ticket+"张票");
            }else break;
        }
    }
}

同步代码块

(可以解决问题)

public class ss {
    public static void main(String[] args) throws InterruptedException {
        MyThread t1=new MyThread();
        MyThread t2=new MyThread();
        MyThread t3=new MyThread();

        t1.setName("窗口1");
        t2.setName("窗口2");
        t3.setName("窗口3");

        t1.start();
        t2.start();
        t3.start();
    }
}
public class MyThread extends Thread{

    static int ticket=0;//这个类所有对象共享ticket数据(加了static)

    static Object obj=new Object();
    @Override
    public void run() {
        while (true){
            synchronized (obj){
                if(ticket<100){
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                    ticket++;
                    System.out.println(getName()+"正在卖第"+ticket+"张票");
                }else break;
            }
        }
    }
}

同步方法:

就是把synchronized关键字加到方法上

public class ss {
    public static void main(String[] args) throws InterruptedException {
        MyRunnable mr=new MyRunnable();

        Thread t1=new Thread(mr);
        Thread t2=new Thread(mr);
        Thread t3=new Thread(mr);

        t1.setName("窗口1");
        t2.setName("窗口2");
        t3.setName("窗口3");

        t1.start();
        t2.start();
        t3.start();
    }
}
public class MyRunnable implements Runnable{
    int ticket=0;
    @Override
    public void run() {
        while (true){
                if (method()) break;
        }
    }

    private synchronized boolean method() {
        if(ticket==100){
            return true;
        }else{
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            ticket++;
            System.out.println(Thread.currentThread().getName()+"在卖第"+ticket+"张票");
        }
        return false;
    }
}

lock锁

死锁

等待唤醒机制

1.消费者

2.生产者

public class Test {
    public static void main(String[] args) {
        Cook c=new Cook();
        Foodie f=new Foodie();

//        c.setName("厨师");
//        f.setName("吃货");

        c.start();
        f.start();
    }
}
public class Foodie extends Thread{
    @Override
    public void run() {
        while (true){
            synchronized (Desk.lock){
                if(Desk.count==0){
                    break;
                }else{
                    if(Desk.foodFlag==0){
                        try {
                            Desk.lock.wait();
                        } catch (InterruptedException e) {
                            throw new RuntimeException(e);
                        }
                    }
                    else{
                        Desk.count--;
                        System.out.println("吃货还能吃"+Desk.count+"碗");
                        Desk.lock.notifyAll();
                        Desk.foodFlag=0;
                    }
                }
            }
        }
    }
}
public class Cook extends Thread{
    @Override
    public void run() {
        while (true){
            synchronized (Desk.lock){
                if(Desk.count==0){
                    break;
                }else {
                    if (Desk.foodFlag==1){
                        try {
                            Desk.lock.wait();
                        } catch (InterruptedException e) {
                            throw new RuntimeException(e);
                        }
                    }else {
                        System.out.println("厨师做了一碗面条");
                        Desk.foodFlag=1;
                        Desk.lock.notifyAll();
                    }
                }
            }
        }
    }
}
public class Desk {
    public static int foodFlag=0;//桌上是否有食物

    public static int count=10;

    public static Object lock=new Object();

}

利用阻塞队列方式实现

import java.util.concurrent.ArrayBlockingQueue;

public class Test {
    public static void main(String[] args) {
        ArrayBlockingQueue<String> queue=new ArrayBlockingQueue<>(1);

        Cook c=new Cook(queue);
        Foodie f=new Foodie(queue);

        c.start();
        f.start();

    }
}
import java.util.concurrent.ArrayBlockingQueue;

public class Foodie extends Thread{
    ArrayBlockingQueue<String> queue;

    public Foodie(ArrayBlockingQueue<String>queue){
        this.queue=queue;
    }
    @Override
    public void run() {
        while (true){
            try {
                String food=queue.take();
                System.out.println(food);

            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }
}
public class Desk {
    public static int foodFlag=0;//桌上是否有食物

    public static int count=10;

    public static Object lock=new Object();

}
import java.util.concurrent.ArrayBlockingQueue;

public class Cook extends Thread{
    ArrayBlockingQueue<String> queue;

    public Cook(ArrayBlockingQueue<String>queue){
        this.queue=queue;
    }

    @Override
    public void run() {
        while (true){
            try {
                queue.put("面条");
                System.out.println("厨师做了一碗面条");
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

多线程的6种状态

 线程池:

1.创建线程池

2.提交任务

3.所有任务全部执行完毕,关闭线程池

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class n {
    public static void main(String[] args) {
//    1.获取线程池对象
//        ExecutorService pool1=Executors.newCachedThreadPool();//无上限
        ExecutorService pool1=Executors.newFixedThreadPool(3);//有上限

//    2.提交任务
        pool1.submit(new MyRunnable());
        pool1.submit(new MyRunnable());
        pool1.submit(new MyRunnable());
        pool1.submit(new MyRunnable());

//    3.销毁线程池
        pool1.shutdown();
    }
}
public class MyRunnable implements Runnable{
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println(Thread.currentThread().getName()+"---"+i);
        }
    }
}

自定义线程池

回头再看

最大并行数

4核8线程:最大并行数8

public class sa {
    public static void main(String[] args) {
        int count=Runtime.getRuntime().availableProcessors();
        System.out.println(count);
    }
}

线程池多大合适

CPU密集型运算 最大并行数+1

I/O密集型运算 最大并行数*期望CPU利用率*(总时间(CPU计算时间+等待时间)/CPU计算时间)

多线程的额外扩展内容

回头再看

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/469817.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

《UE5_C++多人TPS完整教程》学习笔记28 ——《P29 Mixamo 动画(Mixamo Animations)》

本文为B站系列教学视频 《UE5_C多人TPS完整教程》 —— 《P29 Mixamo动画&#xff08;Mixamo Animations&#xff09;》 的学习笔记&#xff0c;该系列教学视频为 Udemy 课程 《Unreal Engine 5 C Multiplayer Shooter》 的中文字幕翻译版&#xff0c;UP主&#xff08;也是译者…

MySQL数据自动同步到Es

Logstash 测试数据准备 DROP DATABASE IF EXISTS es;CREATE DATABASE es DEFAULT CHARACTER SET utf8;USE es;CREATE TABLE book (id INT NOT NULL,title VARCHAR(20),author VARCHAR(20),price DECIMAL(6,2),PRIMARY KEY(id) );DROP PROCEDURE IF EXISTS batchInsertBook;DELI…

飞桨AI应用@riscv OpenKylin

在riscv编译安装飞桨PaddlePaddle参见&#xff1a; 算能RISC-V通用云编译飞桨paddlepaddleopenKylin留档_在riscv下进行paddlelite源码编译-CSDN博客 安装好飞桨&#xff0c;就可以用飞桨进行推理了。刚开始计划用ONNX推理&#xff0c;但是在算能云没有装上&#xff0c;所以最…

第六篇:视频广告格式上传指南(上) - IAB视频广告标准《数字视频和有线电视广告格式指南》

第六篇&#xff1a; 视频广告格式和上传指南&#xff08;上&#xff09; --- 我为什么要翻译介绍美国人工智能科技公司IAB系列技术标准&#xff08;2&#xff09; 流媒体数字视频的广告格式分为线性和非线性两大类。任何一个广告都可以与显示在视频播放器外部的伴随横幅一起提…

教你读懂cert-manager官网并且使用letsencrypt(一)。

这一篇文章主要讲如果通过cert-manager letsencrypt的方式 自动管理你的证书。 一、怎么装&#xff1f; Installation - cert-manager Documentation 选个符合你环境的&#xff0c;推荐helm来管理你的应用。 二、怎么用&#xff1f; 官网说的&#xff1a; 意思就是你安装了…

Positive Technologies 专家发现的漏洞已在 ABB 控制器中得到修复

&#x1f31f; 我们的同事一如既往地表现出色&#xff1a;应用分析专家 Natalia Tlyapova 和 Denis Goryushev 因发现 Freelance AC 900F 和 AC 700F 控制器中的两个漏洞而受到 ABB 的表彰。 这些设备用于自动化大规模连续循环生产设施和构建企业配送控制系统。利用这些漏洞的…

java算法第28天 | 93.复原IP地址 78.子集 90.子集II

93.复原IP地址 思路&#xff1a; 这里startIndex为插入‘.’的位置&#xff0c;使用回溯法遍历所有插入的位置&#xff0c;直接在原始字符串上操作。要注意的是开闭区间的规定&#xff08;这里我规定的是左闭右闭区间&#xff09;。还要明确什么时候能return。 class Solution…

应用案例多且广 八轴测径仪凭什么备受轧钢客户青睐?

在当今高速发展的工业领域&#xff0c;高效、精准的在线测量设备已经成为了企业提高生产效率和产品质量的重要保障。八轴测径仪&#xff0c;作为一款高精度、高效率的在线测量设备&#xff0c;广泛应用于钢铁、冶金、机械制造等行业。 它采用了先进的光学测量技术和智能算法&am…

前端 - 基础 表单标签 -- 表单元素( input - type属性) 文本框和密码框

表单元素 &#xff1a; 在表单域中可以定义各种表单元素&#xff0c;这些表单元素就是允许用户在表单中输入或选择 的内容控件。 表单元素的外观也各不一样&#xff0c;有小圆圈&#xff0c;有正方形&#xff0c;也有方框&#xff0c;乱七八糟的&#xff0c;各种各样&#xf…

网络工程师之路由交换技术篇

网络工程师之路由交换技术篇 路由交换之技术篇ARPICMPBPDUIPv6IP编址MAC其他技术点参考 以下均为个人笔记&#xff0c;摘录到csdn做备份 路由交换之技术篇 ARP Operation Code指定了ARP报文的类型&#xff0c; 包括ARP request 和ARP reply&#xff1b;取值为1或者2 &#x…

代码学习记录22--回溯算法第三天

随想录日记part22 t i m e &#xff1a; time&#xff1a; time&#xff1a; 2024.03.17 主要内容&#xff1a;今天主要是结合类型的题目加深对回溯算法的理解&#xff1a;1.组合总和;2.组合总和 ;3.分割回文串。 39. 组合总和 40.组合总和II131.分割回文串 Topic1组合总和 题…

Leetcode 79. 单词搜索

心路历程&#xff1a; 做完这道题才发现是回溯&#xff0c;一开始想的是递归&#xff0c;判断完第i个字符后&#xff0c;只需要挨个判断第i1个字符在不在第i个字符的邻域。后来发现由于不能重复使用元素&#xff0c;所以需要维护一个visited列表&#xff0c;并且在遍历所有可能…

嵌入式3-19

1、哈希表的代码写完&#xff0c;写出给出关键字&#xff0c;找到该关键字在哈希表(指针数组)中下标的位置&#xff0c;以及在链表中的位置。(因为返回值只有一个&#xff0c;所以结果直接找到通过输出语句输出) void search(node *H,int key); 2、快速排序和折半查找的代码写…

Maven项目如何导入依赖包

一、导入依赖包 导入mysql依赖包 第一步&#xff1a;登录Maven官网 Maven官网&#xff1a;https://mvnrepository.com/search?qmysql 第二步&#xff1a;点击MySql Connector Java 第三步&#xff1a;点击任意一个版本 第四步&#xff1a;将以下内容复制到pom.xml中 导入j…

Unity发布webgl设置占满浏览器运行

Unity发布webgl设置占满浏览器运行 Unity发布webgl的时候index.html的模板文件 模板文件路径&#xff0c;根据自己的需求修改。 C:\Program Files\Unity\Hub\Editor\2021.1.18f1c1\Editor\Data\PlaybackEngines\WebGLSupport\BuildTools\WebGLTemplates\Default再桌面新建一个t…

随笔-生老病死

周末两天也没有出门&#xff0c;帮着一个朋友做了些图&#xff08;就这两天忙不过来&#xff09;&#xff0c;挣了点外快&#xff08;700&#xff09;&#xff0c;累得腰酸、眼花、脖子疼。 媳妇带着小孩出去玩&#xff0c;中间发了个视频&#xff0c;是小孩进了一个围棋培训班…

HTML基础:列表标签的3种形式以及嵌套列表

你好&#xff0c;我是云桃桃。 一个希望帮助更多朋友快速入门 WEB 前端程序媛。 g.zh后台回复“前端工具”可免费获取开发工具&#xff0c;持续更新 今天聊聊列表标签。列表标签&#xff0c;在网页设计中可以帮助将信息以结构化的方式呈现给用户&#xff0c;提高信息的可读性…

在线教育平台帮助教培机构打造线上

随着互联网的迅猛发展&#xff0c;在线教育逐渐成为了教育行业的主流趋势。为了满足教育机构和学生对高效、便捷在线教育的需求&#xff0c;乔拓云教育系统应运而生。该系统以学员端展示课程和后台管理教务为核心功能&#xff0c;为教育机构提供了一站式解决方案&#xff0c;助…

母亲的奶牛(bfs)

农夫约翰有三个容量分别为 A , B , C A,B,C A,B,C 升的挤奶桶。 最开始桶 A A A 和桶 B B B 都是空的&#xff0c;而桶 C C C 里装满了牛奶。 有时&#xff0c;约翰会将牛奶从一个桶倒到另一个桶中&#xff0c;直到被倒入牛奶的桶满了或者倒出牛奶的桶空了为止。 这一过…

晶圆制造过程中常用载具的类型

晶圆载具用于硅片生产、晶圆制造以及工厂之间晶圆的储存、传送、运输以及防护。晶圆载具种类很多,如FOUP用于晶圆制造工厂中晶圆的传送;FOSB用于硅片生产与晶圆制造工厂之间的运输;CASSETTE载具可用于工序间运送以及配合工艺使用。 OPEN CASSETTE OPEN CASSETTE主要在晶圆…