多线程

作者: 月如钩dgf | 来源:发表于2021-09-03 22:58 被阅读0次

synchronized:

synchronized 三种方式来加锁

1.修饰实例方法,作用于当前实例加锁,进入同步代码前要获得当前实例的锁
2.静态方法,作用于当前类对象加锁,进入同步代码前要获得当前类对象的锁
3.修饰代码块,指定加锁对象,对给定对象加锁,进入同步代码库前要获得给定对象的锁。


synchronize基本用法
synchronized原理分析

Java对象头和monitor是实现synchronized的基础。
线程在获取锁的时候,实际上就是获得一个监视器对象(monitor) ,monitor 可以认为是一个同步对象,所有的Java 对象是天生携带 monitor。而monitor是添加Synchronized关键字之后独有的。synchronized同步块使用了monitorenter和monitorexit指令实现同步,这两个指令,本质上都是对一个对象的监视器(monitor)进行获取,这个过程是排他的,也就是说同一时刻只能有一个线程获取到由synchronized所保护对象的监视器。
线程执行到monitorenter指令时,会尝试获取对象所对应的monitor所有权,也就是尝试获取对象的锁,而执行monitorexit,就是释放monitor的所有权
参考帖子

sync 和 Lock的区别

synchronized是关键字,是JVM层面的底层啥都帮我们做了,而Lock是一个接口,是JDK层面的有丰富的API。
synchronized会自动释放锁,而Lock必须手动释放锁。
synchronized是不可中断的,Lock可以中断也可以不中断。
通过Lock可以知道线程有没有拿到锁,而synchronized不能。
synchronized能锁住方法和代码块,而Lock只能锁住代码块。
Lock可以使用读锁提高多线程读效率。
synchronized是非公平锁,ReentrantLock可以控制是否是公平锁。
ThreadLocal详解ThreadLocal在一个线程中是共享的,在不同线程之间又是隔离的”,每个线程都只能看到自己线程的值,这也就是ThreadLocal的核心作用:实现线程范围的局部变量
ThreadLocal应用场景内存泄漏,数据库链接

公平锁与非公平锁

锁Lock分为“公平锁”和“非公平锁”。

公平锁:表示线程获取锁的顺序是按照线程加锁的顺序来的进行分配的,即先来先得FIFO先进先出顺序。

非公平锁:一种获取锁的抢占机制,是随机拿到锁的,和公平锁不一样的是先来的不一定先拿到锁,这个方式可能造成某些线程一直拿不到锁,结果就是不公平的·。

ReentrantReadWriteLock类

类ReentrantLock具有完全互斥排他的效果,即同一时间只有一个线程在执行ReentrantLock.lock()方法后的任务。这样虽然保证了实例变量的线程安全性,但是效率低下。所以在Java中提供有读写锁ReentrantReadWriteLock类,使其效率可以加快。在某些不需要操作实例变量的方法中,完全可以使用ReentrantReadWriteLock来提升该方法代码运行速度。

读写锁表示两个锁:

读操作相关的锁,也成为共享锁。

写操作相关的锁,也叫排他锁。

多个读锁之间不互斥,读锁与写锁互斥,多个写锁互斥。

在没有线程Thread进行写入操作时,进行读操作的多个Thread可以获取读锁,但是进行写入操作时的Thread只有获取写锁后才能进行写入操作。

volatile的用法

volatile通常被比喻成"轻量级的synchronized",也是Java并发编程中比较重要的一个关键字。和synchronized不同,volatile是一个变量修饰符,只能用来修饰变量。无法修饰方法及代码块等。

volatile的用法比较简单,只需要在声明一个可能被多线程同时访问的变量时,使用volatile修饰就可以了。

Executors提供四种线程池

1、newCachedThreadPool创建⼀个可缓存线程池,如果线程池⻓度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
2、newFixedThreadPool 创建⼀个定⻓线程池,可控制线程最⼤并发数,超出的线程会在队列中等待。
3、newScheduledThreadPool 创建⼀个定⻓线程池,⽀持定时及周期性任务执⾏。
4、newSingleThreadExecutor 创建⼀个单线程化的线程池,它只会⽤唯⼀的⼯作线程来执⾏任务,保证所有任务

自定义线程池

可以用ThreadPool Executor类创建,它有多个构造方法来创建线程池,用该类很容易实现自定义的线程池

        //创建等待队列   
        BlockingQueue<Runnable> bqueue = new ArrayBlockingQueue<Runnable>(10); 
      // 无界队列。使用无界队列
        LinkedBlockingQueue<Runnable> linkedBlockingQueue = new LinkedBlockingQueue<Runnable>();  
        //创建线程池,池中保存的线程数为4,允许的最大线程数为5  
        ThreadPoolExecutor pool = new ThreadPoolExecutor(4,5,50,TimeUnit.MILLISECONDS,bqueue); 

参数说明:
corePoolSize:线程池中所保存的核心线程数,包括空闲线程。

maximumPoolSize:池中允许的最大线程数。

keepAliveTime:线程池中的空闲线程所能持续的最长时间。

unit:持续时间的单位。

workQueue:任务执行前保存任务的队列,仅保存由execute方法提交的Runnable任务。

比较Executor和new Thread()

new Thread的弊端如下:
a. 每次new Thread新建对象性能差。
b. 线程缺乏统一管理,可能无限制新建线程,相互之间竞争,及可能占用过多系统资源导致死机或oom。
c. 缺乏更多功能,如定时执行、定期执行、线程中断。
相比new Thread,Java提供的四种线程池的好处在于:
a. 重用存在的线程,减少对象创建、消亡的开销,性能佳。
b. 可有效控制最大并发线程数,提高系统资源的使用率,同时避免过多资源竞争,避免堵塞。
c. 提供定时执行、定期执行、单线程、并发数控制等功能。

线程创建的四种方式

第一种:继承Thread类重写run方法......

class Demo3 extends Thread{
        @Override
        public void run() {
            System.out.println("线程demo3");
        }
    }

第二种:实现Runnable接口....

    static class Demo2 implements Runnable {

        @Override
        public void run() {
            System.out.println("demo2");
        }
    }

第三种:实现CallAble<T>接口,重写call方法.....

             class MyCallable implements Callable<String>(){
             //接口的泛型就是返回值类型 可以抛异常,有返回值
               public String call()throws Exception{.....}
                 return "...."  
              }
           FutureTask<String> task=new FutureTask<>(new MyCallable());
           new Thread(task,"MyCallable").start();

第四种:通过线程池进行创建,用线程池执行Runnable和Callable的实例。

线程的生命周期

第一种状态:初始态,就是new出来还没调用start方法;
第二种状态:运行态,这里需要注意了就绪也是运行状态
包括正在运行中和就绪,这两种都获得了运行所需要的资源等待CPU的调度即可
第三种状态:阻塞态,指没有获取到执行所需要的锁;
第四种状态:等待态,指正在运行中的线程调用了某些方法,比如时wait方法
此时释放了锁同时也没有了CPU的执行权,必须等待其他线程的唤醒,
比如notify或者notifyAll方法,醒来之后如果获取到了锁就会进入
运行态,如果获取锁失败则进入阻塞状态;
第五种状态:超时等待态,指正在执行中线程调用了某些方法,比如sleep方法
此时该线程没有了CPU执行权,但是却没有释放锁,
休眠时间到了会自动进入运行状态;
第六种:终止态,线程运行完了。

相关文章

  • iOS多线程 NSOperation

    系列文章: 多线程 多线程 pthread、NSThread 多线程 GCD 多线程 NSOperation 多线...

  • iOS多线程 pthread、NSThread

    系列文章: 多线程 多线程 pthread、NSThread 多线程 GCD 多线程 NSOperation 多线...

  • iOS多线程: GCD

    系列文章: 多线程 多线程 pthread、NSThread 多线程 GCD 多线程 NSOperation 多线...

  • iOS多线程运用

    系列文章: 多线程 多线程 pthread、NSThread 多线程 GCD 多线程 NSOperation 多线...

  • iOS多线程基础

    系列文章: 多线程 多线程 pthread、NSThread 多线程 GCD 多线程 NSOperation 多线...

  • 多线程介绍

    一、进程与线程 进程介绍 线程介绍 线程的串行 二、多线程 多线程介绍 多线程原理 多线程的优缺点 多线程优点: ...

  • iOS进阶之多线程管理(GCD、RunLoop、pthread、

    深入理解RunLoopiOS多线程--彻底学会多线程之『GCD』iOS多线程--彻底学会多线程之『pthread、...

  • iOS多线程相关面试题

    iOS多线程demo iOS多线程之--NSThread iOS多线程之--GCD详解 iOS多线程之--NSOp...

  • 多线程之--NSOperation

    iOS多线程demo iOS多线程之--NSThread iOS多线程之--GCD详解 iOS多线程之--NSOp...

  • iOS多线程之--NSThread

    iOS多线程demo iOS多线程之--NSThread iOS多线程之--GCD详解 iOS多线程之--NSOp...

网友评论

      本文标题:多线程

      本文链接:https://www.haomeiwen.com/subject/wdlfwltx.html