精华内容
下载资源
问答
  • 多线程原理和使用场景
    2019-11-13 20:37:55

    1,多线程的使用场景

    1. 使用多线程来上传大量视频,充分利用多核CPU资源;
    2. 使用多线程来进行异步处理,由于业务逻辑时间较长,可以开启多线程去处理业务逻辑,主线程直接返回结果;
    3. 使用多线程来统计1000000以内求得的素数个数,可以开启3个线程,第一个线程从2开始,每次+3;第二个线程从3开始,每次+3;第三个线程从4开始,每次+3;同时利用一个原子类来统计总的个数。
      final CountDownLatch latch = new CountDownLatch(2);
      // 递减锁存器的计数,如果计数到达零,则释放所有等待的线程
      latch.countDown();
      // 使当前线程在 锁存器 倒计数为0之前一直等待,除非线程被中断。
      latch.await();
      数据迁移也可以利用多线程进行处理。
      4,定时任务这一块,我使用多线程去定时打标和定时发邮件;充分利用多核CPU资源。

    参考博客:线程池的使用场景深入理解java线程池

    更多相关内容
  • 多线程的实现和使用场景

    万次阅读 多人点赞 2021-06-09 22:06:20
    多线程的实现和使用场景一、多线程实现方式1.1 Thread实现1.2 Runnable实现二、多线程使用场景1.多线程使用场景1.1 多线程应该最多的场景:1.2多线程的常见应用场景:2.多线程小案列2.1 多线程计算2.2 多线程实现...

    一、多线程实现方式

    1.1 Thread实现

    继承Thread类并重写它的run方法。之后创建这个子类的对象并调用start()方法。下面直接上代码:

    /**
    *描述
    * @author cy
    * @date 2021-06-09
    * @return
    **/
    public class TreadTest  extends  Thread{
        public static void main(String[] args) {
            //创建两个线程
            TreadTest thread1 = new TreadTest();
            TreadTest thread2 = new TreadTest();
            thread1.start();
            thread2.start();
        }
        @Override
        public void run() {
           for (int i = 0;i < 100;i++){
               //分别打印线程名称和i
               System.out.println("threadName:"
               +Thread.currentThread()+";i="+i);
           }
        }
    }
    

    输出结果可以看到两个线程交替打印。线程启动成功。
    在这里插入图片描述

    1.2 Runnable实现

    Runnable的实现方式是实现其接口,下面请看具体的实现代码

    
    /**
     * @author  cy
     * @date  2021-06-09
     *@deprecated  Runnable实现多线程
     */
    public class RunnableDemoTest {
    
        public static void main(String[] args) {
            //新建两个线程
            RunnableDemoTest1 r =  
            new RunnableDemoTest1();
            new Thread(r).start();
            new  Thread(r).start();
        }
    
        /**
         * 通过runnable 方式实现多线程
          */
    static class  RunnableDemoTest1  
                       implements  Runnable{
        @Override
        public void run() {
            for (int i = 0 ;i < 5 ;i++)
                System.out.println("threadName:"
                +Thread.currentThread()+";i="+i);
        }
    }
    }
    
    

    从输出结果中我们可以看到两个线程交替打印。线程启动成功。
    在这里插入图片描述

    二、多线程的使用场景

    1.多线程使用场景

    1.1 多线程应该最多的场景:

    web服务器本身; 各种专用服务器(如游戏服务器);

    1.2多线程的常见应用场景:

    1、后台任务,例如:定时向大量(100w以上)的用户发送邮件; 2、异步处理,例如:发微博、记录日志等; 3、分布式计算

    2.多线程小案列

    2.1 多线程计算

    计算一亿个数字之和,在没有学习多线程之前,也是可以实现的,我们可以通过循环一亿次进行累加,最后得出结果。
    代码如下:

    package trhead;
    
    import java.util.Random;
    
    /**
     * 计算一亿个数之和
     */
    public class SumThreadDemo {
    
        private static double [] nums = new double[1_0000_0000];
        private static Random r  =  new Random();
        private static  double  result = 0.0,result1 = 0.0,result2 = 0.0;
    
        static {
            for (int i =0;i < nums.length ; i++){
                nums[i] = r.nextDouble();
            }
        }
    
        public static void main(String[] args) throws InterruptedException {
            SumThreadDemo.m1();
            SumThreadDemo.m2();
        }
    
        /**
         * 使用单线程计算
         */
        private  static  void m1(){
            long startTime = System.currentTimeMillis();
            for (int i = 0;i < nums.length;i++){
                result += nums[i];
            }
            System.out.println(result);
            long endTime = System.currentTimeMillis();
            long countTime = endTime - startTime;
            System.out.println("m1耗时:"+countTime);
        }
    
        /**
         * 使用多线程计算
         */
        private  static  void m2() throws InterruptedException {
    
    
            Thread thread1 =   new Thread(()->{
                for (int i = 0;i < nums.length/2;i++){
                    result1 += nums[i];
                }
            });
    
            Thread thread2 =   new Thread(()->{
                for (int i = nums.length/2;i < nums.length;i++){
                    result2 += nums[i];
                }
            });
            long startTime = System.currentTimeMillis();
            thread1.start();
            thread2.start();
            thread1.join();
            thread2.join();
            System.out.println(result1+ result2);
            long endTime = System.currentTimeMillis();
            long countTime = endTime - startTime;
            System.out.println("m2耗时:"+countTime);
        }
    
    
    
    }
    
    

    从输出结果中可以观察出,两个线程计算结果比单个线程快了将近两倍。如果实际应用中有这种场景,大家可以使用多线程实现。
    在这里插入图片描述

    2.2 多线程实现卖票小程序

    某电影院正在上映某大片,共5张票,而他又有3个售票窗口售票,请设计一个程序模拟该电影院售票。

    多线程实现方式1:

    package trhead;
    
    /**
    *描述
     *  某电影院正在上映某大片,共5张票,
     * 而他又有3个售票窗口售票,请设计一个程序模拟该电影院售票。
    * @author cy
    * @date 2021-06-09
    * @return
    **/
    public class TicketTreadTest extends  Thread{
        //设置票数
        private  int ticket = 5;
        public static void main(String[] args) {
            //创建两个线程
            TicketTreadTest thread1 
                  = new TicketTreadTest();
            TicketTreadTest thread2 
                  = new TicketTreadTest();
            TicketTreadTest thread3 
                  = new TicketTreadTest();
            thread1.start();
            thread2.start();
            thread3.start();
        }
        @Override
        public void run() {
            while(true){
               //分别打印线程名称 和 ticket 数
               System.out.println("threadName:"
               +Thread.currentThread()+";
               ticket="+ticket--);
               if(ticket < 0){
                   break;
                }
           }
        }
    }
    

    结果分析:从下图输出结果中可以分析,使用继承Thread类实现卖票,导致每个窗口都卖了五张票,而这个电影院总共才五张票,多线程出现了超卖现象。原因是继承Thread方式,是多线程多实例,无法实现资源的共享
    在这里插入图片描述

    2.3多线程卖票小程序优化

    在2.2的小程序案列中,我们发现了在多线程的环境下, 由于公共资源可能会被多个线程共享, 也就是多个线程可能会操作同一资源. 当多个线程操作同一块资源时, 很容易导致数据错乱或发生数据安全问题,
    即: 数据有可能丢失, 有可能增加, 有可能错乱.

    我们如何避免这种现象呢?具体看代码:

    package trhead;
    
    /**
     * @author  cy
     * @date  2021-06-09
     *@deprecated  Runnable实现多线程卖票
     */
    public class TicketRunnableDemoTest {
        //设置票数
        private  static int ticket = 5;
    
        public static void main(String[] args) {
            //新建两个线程
            RunnableDemoTest1 r 
                   =  new RunnableDemoTest1();
            new Thread(r).start();
            new  Thread(r).start();
        }
    
        /**
         * 通过runnable 方式实现多线程
          */
    static class  RunnableDemoTest1  
                        implements  Runnable{
        @Override
        public void run() {
            while (ticket > 0){
                saleTicket();
            }
        }
    
            /**
             * 实现卖票方法
             */
        public  void  saleTicket(){
            if(ticket>0){
                System.out.println("threadName:"
                +Thread.currentThread()
                + "正在出票,余票剩余:"+ticket-- +"张");
            }
        }
    }
    }
    
    

    结果分析:从下图输出结果中可以分析,实现Runnable接口进行卖票,电影院总共才五张票,多线程卖票正常。原因是实现Runnable方式,是多线程单实例,可实现资源的共享

    在这里插入图片描述

    2.4多线程卖票小程序优化升级

    细心的小伙伴可能会发现,怎么在2.3输出打印的票数不是从大到小排序的,这跟现实中的卖票场景不一样呐。如果想解决这样的问题,就必须使用同步,所谓的同步就是指多个操作在同一个时间段内只有一个线程进行,其他线程要等待此线程完成之后才可以继续执行
    下面我们通过对2.3代码进行继续优化,实现真实卖票场景。

     /**
    * 通过synchronized实现线程同步
      * 实现卖票方法
      */ public synchronized   void   saleTicket1(){
          if(ticket>0){
              System.out.println("threadName:"
              +Thread.currentThread()
                      + "正在出票,余票剩余:"
                      + +ticket-- +"张");
          }
      }
    

    结果分析:从下图输出结果中可以分析,通过同步代码的方法进行代码的加锁操作,实现了卖票场景。
    在这里插入图片描述


    总结

    这节主要给大家介绍了多线程的实现以及相应的一些使用场景,并且引入了同步的知识点,下一节主要介绍synchronized关键字的使用。
    另外,码字不容易,如果发现小编描述有误,麻烦指摘。

    展开全文
  • 认识多线程多线程使用场景

    千次阅读 2019-08-01 10:13:24
    1 一个对象里面如果有个synchronized方法,某一个时刻内,只要一个线程去调用 其中的一个synchronized方法了,其它的线程都只能等待,换句话说,某一个时刻 内,只能有唯一一个线程去访问这些synchronized方法 2 ...

    1  一个对象里面如果有多个synchronized方法,某一个时刻内,只要一个线程去调用
    其中的一个synchronized方法了,其它的线程都只能等待,换句话说,某一个时刻
    内,只能有唯一一个线程去访问这些synchronized方法
    2  锁的是当前对象this,被锁定后,其它的线程都不能进入到当前对象的其它的
    synchronized方法
    3  加个普通方法后发现和同步锁无关
    4  换成两个对象后,不是同一把锁了,情况立刻变化。
    5  都换成静态同步方法后,情况又变化
    所有的非静态同步方法用的都是同一把锁——实例对象本身,也就是说如果一个实
    例对象的非静态同步方法获取锁后,该实例对象的其他非静态同步方法必须等待获
    取锁的方法释放锁后才能获取锁,可是别的实例对象的非静态同步方法因为跟该实
    例对象的非静态同步方法用的是不同的锁,所以毋须等待该实例对象已获取锁的非
    静态同步方法释放锁就可以获取他们自己的锁。
    所有的静态同步方法用的也是同一把锁——类对象本身,这两把锁是两个不同的对
    象,所以静态同步方法与非静态同步方法之间是不会有竞态条件的。但是一旦一个
    静态同步方法获取锁后,其他的静态同步方法都必须等待该方法释放锁后才能获取
    锁,而不管是同一个实例对象的静态同步方法之间,还是不同的实例对象的静态同
    步方法之间,只要它们同一个类的实例对象!

    展开全文
  • ThreadLocal的原理和使用场景

    千次阅读 2022-04-06 21:41:57
    每一个 Thread 对象均含有一个 ThreadLocalMap 类型的成员变量 threadLocals ,它存储本线程中所 有ThreadLocal对象及其对应的值。 ThreadLocalMap 由一个个 Entry 对象构成 Entry 继承自 WeakReference<...

    每一个 Thread 对象均含有一个 ThreadLocalMap 类型的成员变量 threadLocals ,它存储本线程中所
    有ThreadLocal对象及其对应的值。

    ThreadLocalMap 由一个个 Entry 对象构成

    Entry 继承自 WeakReference<ThreadLocal<?>> ,一个 Entry 由 ThreadLocal 对象和 Object 构成(Object就是我们要存的值)。由此可见, Entry 的key是ThreadLocal对象,并且是一个弱引用。当没指向key的强引用后,该key就会被垃圾收集器回收

    当执行set方法时,ThreadLocal首先会获取当前线程对象,然后获取当前线程的ThreadLocalMap对
    象。再以当前ThreadLocal对象为key,将值存储进ThreadLocalMap对象中。

    get方法执行过程类似。ThreadLocal首先会获取当前线程对象,然后获取当前线程的ThreadLocalMap
    对象。再以当前ThreadLocal对象为key,获取对应的value。

    由于每一条线程均含有各自私有的ThreadLocalMap容器,这些容器相互独立互不影响,因此不会存在线程安全性问题,从而也无需使用同步机制来保证多条线程访问容器的互斥性。

    使用场景:
    1、在进行对象跨层传递的时候,使用ThreadLocal可以避免多次传递,打破层次间的约束。
    2、线程间数据隔离
    3、进行事务操作,用于存储线程事务信息。
    4、数据库连接,Session会话管理。

    Spring框架在事务开始时会给当前线程绑定一个Jdbc Connection,在整个事务过程都是使用该线程绑定的connection来执行数据库操作,实现了事务的隔离性。Spring框架里面就是用的ThreadLocal来实现这种隔离

    在这里插入图片描述

    展开全文
  • ThreadLocal原理使用场景

    千次阅读 多人点赞 2022-01-02 19:56:01
    ThreadLocal ​ ThreadLocal意为线程本地变量,用于解决多线程并发时访问共享变量的问题。 ​ 所谓的共享变量指的是在堆中的实例、静态属性和数组;...​ 很明显,在多线程场景下,当有多个线程对共享
  • 多线程使用的主要目的在于举个简单的例子伪代码多线程的常见应用场景 多线程使用的主要目的在于 1、吞吐量:你做WEB,容器帮你做了多线程,但是他只能帮你做请求层面的。简单的说,可能就是一个请求一个线程。或多...
  • >>号外:关注“Java精选”公众号,菜单栏->聚合->干货分享,回复关键词领取视频资料、开源项目。多线程使用的主要目的在于:1、吞吐量:你做WEB,容器帮你做了多...
  • 来源:cnblogs.com/kenshinobiy/p/4671314.html多线程使用的主要目的在于:1、吞吐量:你做WEB,容器帮你做了多线程,但是他只能帮你做请求层面的。简单的说...
  • Java多线程开发的实际应用场景

    千次阅读 2021-07-28 18:01:05
    SaaS型微服务脚手架,具备用户管理、资源权限管理、网关统一鉴权、Xss防跨站攻击、自动代码生成、存储系统、分布式事务、分布式定时任务等个模块,支持业务系统并行开发, 支持服务并行开发,可以作为后端...
  • 深入了解多线程原理

    万次阅读 多人点赞 2018-05-25 15:35:48
    使用多线程的目的 在多个CPU核心下,多线程的好处是显而易见的,不然多个CPU核心只跑一个线程其他的核心就都浪费了 即便不考虑多核心,在单核下,多线程也是有意义的,因为在一些操作,比如IO操作阻塞的时候,是不...
  • 深入浅出多线程编程实战(五)ThreadLocal详解(介绍、使用原理、应用场景) 文章目录一、ThreadLocal简介二、ThreadLocal与Synchronized区别三、ThreadLocal简单使用四、ThreadLocal原理五、ThreadLocal 应用场景 ...
  • 多线程、多进程的区别及适用场景

    千次阅读 2018-04-11 21:05:11
    对于多进程和多线程,教科书上最经典的一句话是“进程是资源分配的最小单位,线程是CPU调度的最小单位”。多线程占相比于多进程占用内存少、CPU利用率高,创建销毁,切换都比较简单,速度很快。多进程相比于多线程...
  • java多线程join()方法的作用实现原理

    千次阅读 多人点赞 2021-07-04 18:16:45
    应用场景 比如有三个人小红、小李、小王, 三个人相约一起去酒店吃饭,菜已经点好了,三个人从不同的地方出发,只有三个人都到了酒店之后才会开始上菜;那么这三个人就分别代表三个线程,这三个线程执行完之后才会...
  • 并发编程(一)多线程基础和原理

    千次阅读 2020-07-19 01:44:02
    多线程基础 最近,准备回顾下多线程相关的知识体系,顺便在这里做个记录。 并发的发展历史 最早的计算机只能解决简单的数学运算问题,比如正弦、 余弦等。运行方式:程序员首先把程序写到纸上,然后穿 孔成卡片,...
  • JUC多线程:ThreadLocal 原理总结

    千次阅读 2021-10-10 17:49:21
    ThreadLocal 提供了线程内部的局部变量,当在多线程环境中使用 ThreadLocal 维护变量时,会为每个线程生成该变量的副本,每个线程只操作自己线程中的变量副本,不同线程间的数据相互隔离、互不影响,从而保证了线程...
  • 多线程锁的升级原理是什么?

    万次阅读 多人点赞 2019-05-20 11:04:06
    多线程锁的升级原理是什么? 锁的级别从低到高: 无锁 -> 偏向锁 -> 轻量级锁 -> 重量级锁 锁分级别原因: 没有优化以前,sychronized是重量级锁(悲观锁),使用 wait notify、notifyAll 来切换...
  • volatile的原理和使用场景

    千次阅读 2018-07-11 22:08:42
    上下文切换 CPU为每个线程分配时间片(几十ms),CPU不断切换线程执行,切换的时候会...为了降低开销我们应减少上下文切换,多线程竞争锁会引起上线文切换,CAS算法无需加锁,可以减少上线文切换,使用最少线程(...
  • 线程是调度CPU资源的最小单位,线程模型分为KLT模型与ULT模型,JVM使用的KLT模型,一个java线程对应一个OS线程线程个生命状态 ①:NEW :新建 ②:RUNNABLE :运行 ③:BLOCKED :阻塞 ④:WAITING :等待 ⑤...
  • 1. 多线程有什么用? 1) 发挥多核CPU 的优势 随着工业的进步,现在的笔记本、台式机乃至商用的应用服务器至少也都是双核的,4 核、8 核甚至 16 核的也都不少见,如果是单线程的程序,那么在双核 CPU 上就浪费了 50%...
  • 面试中的 ThreadLocal 原理和使用场景 前言 今天博主将为大家分享Java(面试必备):面试中的 ThreadLocal 原理和使用场景,不喜勿喷,如有异议欢迎讨论! 相信大家在面试中经常被问过 ThreadLocal 的原理和...
  • 多线程---详解各种锁AQS原理

    千次阅读 2021-08-08 19:14:57
    多线程-进阶1. synchronized可重入同一个线程不同线程2. volatile保证线程可见性禁止指令重排序查看结果3. 锁优化锁细化锁粗化锁对象4. CAS(无锁优化, 自旋)5. JUC同步锁1. ReentrantLock(可重入锁)同一个线程不同...
  • 1 queue原理 1.1 queue简述 std::queue: 模板类queue定义在<queue>头文件中。队列(Queue)是一个容器适配器(Container adaptor)类型,被特别设计用来运行于FIFO(First-in first-out)场景,在该场景中,只能...
  • 在日常提升Python基本功的时候,可能会被Python的迭代器生成器搞晕,之前在学习和使用时,本来for in 循环体enumerate函数用的飞起,觉得自己已经彻底了解了Python的迭代特性,但接触了迭代器生成器后,突然...
  • 作者简介:笔名seaboat,擅长工程算法、人工智能算法、自然语言处理、架构、分布式、高并发、大数据搜索引擎等方面的技术,大多数编程语言都会使用,但更擅长Java、PythonC++。平时喜欢看书、写作运动,擅长...
  • 多线程在web中的使用

    千次阅读 2018-09-28 15:01:05
    整理网络上的 最典型的如: ... 且这类任务即使失败也不是特别重要的。 2、后台线程:比如定期...最典型的应用比如tomcat,tomcat内部采用的就是多线程。 上百个客户端访问同一个web应用,tomcat接入后都是把后续的处理...
  • java多线程有哪些实际的应用场景

    万次阅读 多人点赞 2017-10-17 10:10:33
    多线程使用的主要目的在于: 1、吞吐量:你做WEB,容器帮你做了多线程,但是他只能帮你做请求层面的。简单的说,可能就是一个请求一个线程。或多个请求一个线程。如果是单线程,那同时只能处理一个用户的请求。 2、...
  • 万字图解Java多线程

    万次阅读 多人点赞 2020-09-06 14:45:07
    我以前也是感觉学会了,但是真正有多线程的需求却不知道怎么下手,实际上还是对多线程这块知识了解不深刻,不知道多线程api的应用场景,不知道多线程的运行流程等等,本篇文章将使用实例+图解+源码的方式来解析java...
  • ThreadLocal使用场景原理分析

    千次阅读 2020-03-18 15:42:09
    使用ThreadLocal维护变量的时候,为每一个使用该变量的线程提供一个独立的变量副本,即每个线程内部都会有一个该变量,这样同时线程访问该变量并不会彼此相互影响,因此他们使用的都是自己从内存中拷贝过来的...
  • 多线程常见的面试题

    万次阅读 2020-09-16 16:21:58
    多线程常见的面试题: 1. 什么是线程进程? 线程与进程的关系,区别及优缺点? 进程是程序的一次执行过程,是系统运行程序的基本单位,因此进程是动态的。系统运行一个程序即是一个进程从创建,运行到消亡的过程。 ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 227,148
精华内容 90,859
关键字:

多线程原理和使用场景