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计算时间)

多线程的额外扩展内容

回头再看

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

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

相关文章

面试算法-51-翻转二叉树

题目 给你一棵二叉树的根节点 root &#xff0c;翻转这棵二叉树&#xff0c;并返回其根节点。 示例 1&#xff1a; 输入&#xff1a;root [4,2,7,1,3,6,9] 输出&#xff1a;[4,7,2,9,6,3,1] 解 class Solution {public TreeNode invertTree(TreeNode root) {dfs(root);re…

【C语言进阶篇】自定义类型:结构体(上)

目录 1. 结构体类型的声明 ​编辑 1.1 结构体的创建和初始化 1.2 结构体的特殊声明 1.3 结构体的自引用 2. 结构体内存对齐 2.1 对齐规则 2.2 为什么存在内存对齐 2.3 修改默认对齐数 在我们描述简单对象的时候&#xff0c;使用已有的类型就足够了&#xff0c;比如: 但是当我们…

堆排序(数据结构)

本期讲解堆排序的实现 —————————————————————— 1. 堆排序 堆排序即利用堆的思想来进行排序&#xff0c;总共分为两个步骤&#xff1a; 1. 建堆 • 升序&#xff1a;建大堆 • 降序&#xff1a;建小堆 2. 利用堆删除思想来进行排序. 建堆和堆删…

代码随想录|Day21|回溯01|77.组合

77.组合 组合问题不考虑顺序&#xff0c;例如 [1, 2] 和 [2, 1] 是同一个组合。其中 n 为取数的范围&#xff0c;每个组合包含 k个 元素数量&#xff0c;所以我们嵌套 k 个 for循环 可以很容易写出暴力解法。但如果 k 的值过大&#xff0c;代码将会非常冗长。 我们考虑回溯&…

基于”Python+”多技术融合在蒸散发与植被总初级生产力估算中的应用教程

原文链接&#xff1a;基于”Python”多技术融合在蒸散发与植被总初级生产力估算中的应用教程https://mp.weixin.qq.com/s?__bizMzUzNTczMDMxMg&mid2247598050&idx5&sn70fd3f5946d581ad9c1363295b130ef5&chksmfa823e05cdf5b713baf9cf1381bfb2455ad675a0b21e194…

Unity类银河恶魔城学习记录11-2 p104 Inventoty源代码

此章节相对较难理解&#xff0c;有时间单独出一章讲一下 Alex教程每一P的教程原代码加上我自己的理解初步理解写的注释&#xff0c;可供学习Alex教程的人参考 此代码仅为较上一P有所改变的代码 【Unity教程】从0编程制作类银河恶魔城游戏_哔哩哔哩_bilibili InventoryItem.cs…

C++ Qt开发:QUdpSocket网络通信组件

Qt 是一个跨平台C图形界面开发库&#xff0c;利用Qt可以快速开发跨平台窗体应用程序&#xff0c;在Qt中我们可以通过拖拽的方式将不同组件放到指定的位置&#xff0c;实现图形化开发极大的方便了开发效率&#xff0c;本章将重点介绍如何运用QUdpSocket组件实现基于UDP的网络通信…

Java安全 反序列化(1) URLDNS链原理分析

Java安全 反序列化(1) URLDNS链原理分析 文章目录 Java安全 反序列化(1) URLDNS链原理分析前置知识应用分析payload1.新建HashMap类2.新建URL类3.获取URL 的 Class对象4.通过反射访问URL内部变量5.通过反射为URL中类赋值6.调用HashMap#put方法传入key和value7.再次通过反射为UR…

基于51单片机PT100温度检测LCD1602显示(程序+原理图+PCB+仿真+全套资料)

功能介绍&#xff1a;采用51单片机和MAX13865模块PT100传感器LCD1602显示屏&#xff0c;通过PT100传感器感知稳定&#xff0c;MAX13865模块进行转换&#xff0c;采用SPI协议和单片机进行通信&#xff0c;将温度传送到单片机&#xff0c;然后单片机将数据显示到LCD1602屏幕上。 …

ModbusTCP转Profinet网关高低字节交换切换

背景&#xff1a;在现场设备与设备通迅之间通常涉及到从一种字节序&#xff08;大端或小端&#xff09;转换到另一种字节序。大端字节序是指高位字节存储在高地址处&#xff0c;而小端字节序是指低位字节存储在低地址处。在不动原有程序而又不想或不能添加程序下可选用ModbusTC…

深入探讨Python中的文件操作与文件IO操作【第141篇—Python实现】

&#x1f47d;发现宝藏 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。【点击进入巨牛的人工智能学习网站】。 深入探讨Python中的文件操作与文件IO操作 在Python编程中&#xff0c;文件操作和文件IO操作…

【Swing】Java Swing实现省市区选择编辑器

【Swing】Java Swing实现省市区选择编辑器 1.需求描述2.需求实现3.效果展示 系统&#xff1a;Win10 JDK&#xff1a;1.8.0_351 IDEA&#xff1a;2022.3.3 1.需求描述 在公司的一个 Swing 的项目上需要实现一个选择省市区的编辑器&#xff0c;这还是第一次做这种编辑器&#xf…

第四百一十一回

文章目录 1. 概念介绍2. 思路与方法2.1 实现思路2.2 实现方法 3. 示例代码4. 内容总结 我们在上一章回中介绍了"给geolocator插件提交问题的结果"相关的内容&#xff0c;本章回中将介绍自定义标题栏.闲话休提&#xff0c;让我们一起Talk Flutter吧。 1. 概念介绍 我…

Java基础-IO流

文章目录 1.文件1.基本介绍2.常用的文件操作1.创建文件的相关构造器和方法代码实例结果 2.获取文件相关信息代码实例结果 3.目录的删除和文件删除代码实例 2.IO流原理及分类IO流原理IO流分类 3.FileInputStream1.类图2.代码实例3.结果 4.FileOutputStream1.类图2.案例代码实例 …

全国农产品价格分析预测可视化系统设计与实现

全国农产品价格分析预测可视化系统设计与实现 【摘要】在当今信息化社会&#xff0c;数据的可视化已成为决策和分析的重要工具。尤其是在农业领域&#xff0c;了解和预测农产品价格趋势对于农民、政府和相关企业都至关重要。为了满足这一需求&#xff0c;设计并实现了全国农产…

Apache SeaTunnel MongoDB CDC 使用指南

随着数据驱动决策的重要性日益凸显&#xff0c;实时数据处理成为企业竞争力的关键。SeaTunnel MongoDB CDC(Change Data Capture) 源连接器的推出&#xff0c;为开发者提供了一个高效、灵活的工具&#xff0c;以实现对 MongoDB 数据库变更的实时捕获和处理。 本文将深入探讨该连…

3月19日做题

[NPUCTF2020]验证&#x1f40e; if (first && second && first.length second.length && first!second && md5(firstkeys[0]) md5(secondkeys[0]))用数组绕过first1&second[1] 这里正则规律过滤位(Math.) (?:Math(?:\.\w)?) : 匹配 …

详解命令docker run -d --name container_name -e TZ=Asia/Shanghai your_image

docker run 是Docker的主要命令&#xff0c;用于从镜像启动一个新的容器。下面详细解释并举例说明 -d, --name, -e TZ 参数的用法&#xff1a; -d 或 --detach&#xff1a; 这个标志告诉Docker以守护进程&#xff08;后台&#xff09;模式运行容器。这意味着当你执行 docker ru…

②免费AI软件开发工具测评:通义灵码 VS 码上飞

前言 我又双叒叕来测评了&#xff01;上次给大家带来的是iFlyCode和CodeFlying两款产品的测评&#xff0c;受到了大家的一致好评~ 今天咱就继续来聊聊&#xff0c;这次我们选的的对象是通义灵码和码上飞&#xff0c;从名字上也能看到出来这两款产品一定是跟软件开发有关系的&…

IPD集成产品开发:塑造企业未来竞争力的关键

随着市场竞争的日益激烈&#xff0c;企业对产品开发的要求也越来越高。如何在快速变化的市场环境中&#xff0c;既保证产品的批量生产效率&#xff0c;又满足客户的个性化需求&#xff0c;成为了企业面临的重要挑战。IPD&#xff08;集成产品开发&#xff09;模式&#xff0c;作…
最新文章