• Java之多线程


    进程和线程

    什么是进程:进程是系统进行资源分配单位,是操作系统结构的基础,比如我们在使用微信聊天,当我们启动微信就相当于我们启动了一个进程。

    什么是线程:线程是cpu资源调度的最小单位。一个进程最少有一个线程,

    通常在一个进程中可以包含若干个线程,它们可以利用进程所拥有的资源。在引入线程的操作系统中,通常都是把进程作为分配资源的基本单位,而把线程作为独立运行和独立调度的基本单位。由于线程比进程更小,基本上不拥有系统资源,故对它的调度所付出的开销就会小得多,能更高效的提高系统内多个程序间并发执行的程度,从而显著提高系统资源的利用率和吞吐量。

    线程创建的方法 :4种方式

    一、编写一个类,直接 继承 java.lang.Thread重写 run方法

    1. 怎么创建线程对象? new继承线程的类。
    2. 怎么启动线程呢? 调用线程对象的 start() 方法。

    二、编写一个类,实现 java.lang.Runnable 接口,实现run方法

    1. 怎么创建线程对象? new Thread 传入可运行的类/接口。
    2. 怎么启动线程呢? 调用线程对象的 start() 方法。
    3. 也可以使用匿名内部类方式创建:

    三、编写一个类,实现Callable接口(JDK5.0新增)实现call方法

    该方法效率较低,因为在获取线程的执行结果的时候,当前线程受阻塞。

    但是可以拿到线程的返回结果

    1. //1.创建一个实现Callable的实现类
    2. class NumThread implements Callable{
    3. //2.实现call方法,将此线程需要执行的操作声明在call()中
    4. @Override
    5. public Object call() throws Exception {
    6. int sum = 0;
    7. for(int i = 1;i <= 100;i++){//快捷方式:100.for
    8. if(i % 2 == 0){
    9. System.out.println(i);
    10. sum += i;
    11. }
    12. }
    13. return sum;
    14. }
    15. }
    16. public class ThreadNew {
    17. public static void main(String[] args) {
    18. //3.创建Callable接口实现类的对象
    19. NumThread numThread = new NumThread();
    20. //4.将此Callable接口实现类的对象作为传递到FutureTask构造器中,创建FutureTask的对象
    21. FutureTask futureTask = new FutureTask(numThread);
    22. //5.将FutureTask的对象作为参数传递到Thread类的构造器中,创建Thread对象,并调用start()
    23. new Thread(futureTask).start();
    24. try {
    25. //6.获取Callable中call方法的返回值
    26. //get()返回值即为FutureTask构造器参数Callable实现类重写的call()的返回值。
    27. Object sum = futureTask.get();
    28. System.out.println("总和为:" + sum);
    29. } catch (InterruptedException e) {
    30. e.printStackTrace();
    31. } catch (ExecutionException e) {
    32. e.printStackTrace();
    33. }
    34. }
    35. }

    四、使用线程池创建

    对经常大量创建销毁、使用量特别大的资源,比如并发情况下的线程,对性能的影响很大

    可以提前创建多个线程,放入线程池,使用时候直接获取,使用完之后放回池中。以避免频繁的创建销毁、实现重复利用率 

    好处呢显然就是1、提高响应速度  2、降低资源消耗   3、便于线程管理

    线程池各项参数:

    corePoolSize 代表核心线程数

    maxinumPoolSize 代表的是最大线程数

    keepAliveTime 表示超出核心线程数之外的线程的空闲存活时间

    workQueue 用来存放待执行的任务

    ThreadFactory 实际上是一个线程工厂,用来生产线程执行任务

    Handler 任务拒绝策略,有两种情况,第一种是当我们调用 shutdown 等方法关闭线程池后,这 时候即使线程池内部还有没执行完的任务正在执行,但是由于线程池已经关闭,我们再继续想线程 池提交任务就会遭到拒绝。另一种情况就是当达到最大线程数,线程池已经没有能力继续处理新提 交的任务时,这是也就拒绝。

    1. public class ThreadPool {
    2. public static void main(String[] args) {
    3. // ExecutorService executorService = Executors.newFixedThreadPool(10); //制造一个线程池,里面有10个线程
    4. //注意Executors.newFixedThreadPool是一个接口,需要转换成实现类
    5. ThreadPoolExecutor executorService = (ThreadPoolExecutor)Executors.newFixedThreadPool(10);
    6. //设置线程池的属性
    7. executorService.setCorePoolSize(10); //代表核心线程数,也就是正常情况下创建工作的线程数,这些线程创建后并不会消除,而是一种常驻线程
    8. executorService.setMaximumPoolSize(10); //代表的是最大线程数
    9. executorService.setKeepAliveTime(1000, TimeUnit.MILLISECONDS); // 表示超出核心线程数之外的线程的空闲存活时间
    10. executorService.execute(new NumberThread());//适合适用于Runnable
    11. executorService.execute(new NumberThread2());//适合适用于Runnable
    12. // executorService.submit(); //适合适用于Callable
    13. executorService.shutdown(); //关闭线程池
    14. }
    15. }

    线程池执行流程:

    ​​​​​​​

     

     

     

    当多个线程同时对数据进行访问和修改时,可能会出现数据不准确等问题,使用synchroized加互斥锁始终保持同时只有一个线程能够访问,保证数据安全。

    synchroized关键字互斥锁

    互斥锁 
    1.每个对象都对应于一个可称为“互斥锁”的标记,这个标记用来保证在任一时刻,只能有一个线程访问该对象。
    2.关键字synchronized来与对象的互斥锁联系。当某个对象用synchronized修饰时,。表明该对象在任一时刻只能由一个线程访问
    3.同步的局限性:导致程序的执行效率要降低
    4.同步方法((非静态的)的锁可以是this,也可以是其他对象(要求是同一个对象)

    5.同步方法(静态的)的锁为当前类本身

    方法:

    1、同步代码块

    1. synchronized (对象) { //得到对象的锁,才能操作同步代码,只要是 同一对象都行
    2. //需要同步的代码
    3. }

    2、放在方法上

    非静态同步方法锁默认是加到this上

    1. public synchronized void lock(){ //表示方法为同步方法
    2. //需要背同步的代码
    3. }

    3、放在静态方法上

    注意静态同步方法的锁是加在类名.class,里面代码块也需要类名.class

    1. public static void lock(){ //表示方法为静态同步方法
    2. synchronized(类名.class){
    3. //同步代码块内容
    4. }
    5. }

  • 相关阅读:
    零基础入门推荐系统 - 新闻推荐 - 实操1
    逆向破解之易语言按钮事件特征码
    计算机毕设 基于大数据的抖音短视频数据分析与可视化 - python 大数据 可视化
    路由之间的转跳及传参
    go: 如何编写一个正确的udp服务端
    洛谷_P3388
    DBS note3:B+ Trees
    用半天时间从零开始复习前端之html
    vue使用原生video标签基本功能(不含样式)
    软件流程和管理(六):Project Scheduling
  • 原文地址:https://blog.csdn.net/weixin_52875557/article/details/126329750