多线程

作者: Audience0 | 来源:发表于2019-02-27 00:04 被阅读0次
概念:
    每个正在系统中运行的程序就是一个进程,每个进程包含一个或多个线程,每一个线程相当于进程的一条执行路径,线程则是一组指令的集合,它可以再程序中独立的执行.

  使用多线程的主要目的就是提高程序的执行效率.但过多的线程,同样会影响性能,因为系统需要在多个线程之间频繁的切换,并且维护线程需要内存空间,所有提高程序的效率则要合理的使用线程,一般会设定一个合理的线程池.

创建线程方式:
1.继承Thread类
2.实现Runnable接口,重新run方法,该方法比继承Thread类好,因为继承只能继承一个类,而实现可以实现多个接口.(可以通过匿名内部类去重写run方法)
3.Callable接口与FutureTask类结合方式
>实现Callable接口,重写call()方法,有返回值的线程。
>继承FutureTask类,并传入Callable的实现类。
>FutureTask实现了runnable接口,可以作为目标任务传入Thread
>FutureTask.get() 方法获取线程返回值,该方法会阻塞获取结果的线程,直到call方法返回结果。
>FutureTask.cancel(boolean ) 可以取消线程任务

常用线程的方法:
1.start()启动线程
2.currentThread()获取当前线程对象
3.getID()获取当前线程ID
4.getName()获取当前线程名称
5.sleep(long mill)休眠线程,不释放锁
6.stop()停止线程,不推荐使用,可能导致程序不安全
7.wait()线程等待 ,释放锁
8. notify()/notifyAll() 唤醒 指定对象锁的线程池中的线程
>wait() notify()方法都是在synchronized中使用,使用方法 锁对象.wait()
9.join() 把指定的线程加入到当前线程,将多线程变成单线程
10.interrupt()中断当前线程的状态,变相的中断wait(),sleep()的等待状态,由wait(),sleep()抛出InterruptedException异常,并继续执行catch中的语句
11.Thread.yield() 暂停当前正在执行的线程,使该线程与其他线程重新一起抢CPU时间片.

线程的运行状态:


图片.png

新建状态:当用new操作创建一个线程,此时线程处于新建状态,线程还没有开始运行.
就绪状态:当调用start()方法,即启动了线程,此时线程需要获取CPU时间片才能运行,此时线程处于就绪状态.对于多个处于就绪状态的线程是由Java运行时系统的线程调度程序(thread scheduler)来调度的.
运行状态:当线程获取到CPU时间片后,进行运行状态,开始执行线程run()方法.
阻塞状态:线程运行过程中,可能由于各种原因进入阻塞状态:
1>线程调用sleep()方法进入到睡眠状态.
2>线程调用一个在I/O上被阻塞的操作,即该操作在输入输出操作完成前不会返回到它的调用者.
3>线程试图获取一个锁,而该锁正被其他线程持有
4>线程在等待某个出发条件
死亡状态:有两个原因导致线程死亡:
1>run()方法执行完毕,正常退出,自然死亡
2>一个未捕获的异常终止run()方法而使线程猝死.
3>验证线程是否存活着,可以通过isAlive()方法,如果是可运行或被阻塞时,返回true,如果在新建状态或者死亡状态则返回false.

守护线程:
Java中有两种线程,一种是用户线程, 一种是守护线程.
1>用户线程也就做非守护线程指的是用户自定义创建的线程,主线程停止,用户线程不会停止.
2>守护线程,当进程不存在或主线程停止时,守护线程也会停止,使用setDaemon(true)方法设置为守护线程

线程安全:
当多个线程同时共享同一个全局变量或静态变量时,做写的操作时,可能会发生数据冲突,即线程不安全.但做读操作的时候不会.
解决办法:
1>同步锁synchronized关键字
1>>修饰实例方法 对象锁为this
2>>修饰静态方法 对象锁是当前类的字节码文件,即this.getClass();少用-->占内存,垃圾回收无法处理
3>>修饰代码块 对象锁为synchronized(obj) 指定的obj
4>>解决了线程不安全的情况,但是多个线程需要判断锁,抢锁,比较耗资源
2>lock()锁
1>>重入锁

lock锁和synchronized的区别:
  1>synchronized 是内部锁,自动化的上锁与释放锁,而lock是手动的,需要人为的上锁和释放锁,lock比较灵活,但是代码相对较多
  2>lock接口异常的时候不会自动的释放锁,同样需要手动的释放锁,所以一般写在finally语句块中,而synchronized则会在异常的时候自动的释放锁
3>lock超时获取锁:在指定的截止时间之前获取锁,如果截止时间到了仍旧无法获取锁,则返回
4>lock尝试非阻塞的获取锁:当前线程尝试获取锁,如果这一时刻没有被其他线程获取到,则成功获取并持有锁。
5>lock能被中断的获取锁:获取到锁的线程能够响应中断,当获取到锁的线程被中断时,中断异常将被抛出,同事释放锁。

死锁:同步中嵌套同步,导致锁无法释放(占了A锁的线程欲获取B锁,而占了B锁的线程欲获取A锁.)

多线程三大特性:
1>原子性:即一个操作或多个操作,要么全部执行并执行过程中不会被任何因素打断,要么就都不执行,保证线程安全.(i=i+1 非原子性,i++是原子性的)
2>可见性:当多个线程访问同一个变量时,一个线程修改了这个变量的值,其他线程能够立即看得到修改的值.
3>有序性:程序执行的顺序按照代码的先后顺序执行

Java内存模型(Java Memory Model ,JMM):JMM决定一个线程对共享变量的写入何时对另一个线程可见.
抽象结构:
1>主内存:线程之间的共享变量存储在主内存(Main Memory)中.
2>本地内存:本地内存中存储了该线程以读/写共享变量的副本--抽象概念--它包含了缓存,缓冲区,寄存器等..

volatile关键字作用:使变量在多个线程之间可见,强制线程去主内存中取该数据.

volatile与synchronized区别:
1>volatile轻量级,只能修饰变量,synchronized重量级,还可以修饰方法.
2>volatile只能保证数据的可见性,不能保证线程的安全性(原子性)
3>synchronized不仅保证可见性,而且还保证原子性,因为,只有获得了锁的线程才能进入临界区,从而保证临界区中的所有语句都全部执行。多个线程争抢synchronized锁对象时,会出现阻塞。
4>volatile 禁止重排序(重排序:CPU会对代码执行实现优化,但不会对有依赖关系的做重排序,代码可能改变顺序,但不会改变结果,重排序的意义是提高并行度,但是在多线程情况下有可能有影响到结果,此时需要用volatile)

线程安全包括两个方面:可见性,原子性

ThreadLocal : 本地线程:为每一个线程提供一个本地局部变量
ThreadLocal主要有四个方法:
1>void set(Objectvalue) 设置当前线程的线程局部变量的值.
2>public Object get() 该方法返回当前线程所对应的线程局部变量
3>public void remove()将当前线程局部变量的值删除,目的是为了减少内存的占用.当线程结束后,对应的线程局部变量将自动被垃圾回收,所以显示调用该方法是不是必须的,但是调用它可以加快内存的回收速度.
4>protect Object initialValue()返回该想成局部变量的初始值.protected的方法,显然是为了让子类覆盖而设计的。这个方法是一个延迟调用方法,在线程第1次调用get()或set(Object)时才执行,并且仅执行1次。ThreadLocal中的缺省实现直接返回一个null。

ThreadLocal实现原理:

 public T get() {
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);
        if (map != null) {
            ThreadLocalMap.Entry e = map.getEntry(this);
            if (e != null) {
                @SuppressWarnings("unchecked")
                T result = (T)e.value;
                return result;
            }
        }
        return setInitialValue();
    }

   public void set(T value) {
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);
        if (map != null)
            map.set(this, value);
        else
            createMap(t, value);
    }

锁 线程池 并发包

相关文章

  • 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/gwanyqtx.html