美文网首页
七、多线程

七、多线程

作者: 柳岸 | 来源:发表于2016-10-30 20:59 被阅读0次

一、线程概述

线程是在程序中独立并发的执行流,相比于进程,线程具有更高的性能,多个线程可以共享一个进程虚拟空间,线程之间共享内存非常方便,可以拥有很高的并发。

二、线程的创建和启动

2.1 继承Thread类创建线程类

通过继承Thread类来创建启动多线程的步骤如下:
(1)定义Thread的子类,重写run方法
(2)创建Thread子类的实例
(3)通过start来启动线程
Thread.currentThread()可以返回当前正在执行的线程对象
getName()可以返回线程的名字

public class FirstThread extends Thread{
    public void run()
    {...}
}
new FirstThread().start();

2.2 实现Runnable接口创建线程类

通过Runnable接口来创建并启动多线程的步骤如下:
(1)定义Runnable的实现类,并且重写run方法
(2)创建Runnable实现类的实例,并且以此实例作为Thread的target来创建Thread对象

public class SecondThread implements Runnable
{
    public void run()
    {...}
}
new Thread(st,'name').start();

采用Runnable接口的方式来创建的多条线程可以共享线程类的实例属性。
采用Runnable接口方式来创建的线程只能通过Thread.currentThread()来获取当前线程,而不能通过this

3 线程的生命周期

  • 新建状态:new了一个线程之后
  • 就绪状态:调用了start之后(永远不要直接调用run方法)
  • 运行状态:线程获得CPU,开始运行run方法之后
  • 阻塞状态:调用sleep,调用阻塞式IO方法,等待通知,程序调用了suspend方法等,都会使线程进入阻塞状态。
  • 线程死亡:run()执行完毕,抛出未捕获的Exception和Error,或者调用该程序的stop()方法来结束该线程。

可以通过线程的isAlive方法来判断线程是否死亡
不要试图对一个已经死亡的线程调用start方法

4 控制线程

4.1 join线程

某个线程调用另一个线程的join方法以后,该线程将被阻塞,直到被join的线程执行完毕以后为止。

  • join()
  • join(long millis)
  • join(long millis,int nanos)

4.2 后台线程

后台线程有个特征:如果前台线程都死亡,则后台线程会自动死亡。
通过调用Thread的setDaemon(true)的时候,就可以将其设为后台线程。
可以通过isDaemon()来判断是否是后台线程

4.3 线程睡眠Sleep

  • Thread.sleep(long millis)
  • Thread.sleep(long millis, int nanos)

4.4 线程让步yield

yield方法不会阻塞该线程,而是转入就绪状态,让线程调度器重新调度一次。

  • Thread.yield

4.5 改变线程优先级

  • Thread.setPriority(int newPriority)
    优先级值在1~10之间,也可以使用MAX_PRIORITY(10),MIN_PRIORITY(1),NORM_PRIORITY(5)

5 线程的同步

5.1同步代码块

synchronized(obj){ 同步代码块 }

5.2同步方法

public synchronized void draw(double drawAmount)

5.3释放同步监视器的锁定

以下情况会释放:

  • 代码块执行完毕
  • break return
  • 抛出错误或者异常
  • 程序执行了同步监视器对象的wait()方法

5.4 同步锁

常用的有可重用锁ReentrantLock,可重用的意思是说,对已经加锁的ReentrantLock可以再次上锁,该对象会维持一个计数器来记录。

public class Accout
{
    private final ReetrantLock lock = new ReentrantLock();
    public void draw(double drawAmout)
    {
        lock.lock();
        try
        {
        //临界区
        }
        finally
        {
            lock.unlock();
        }
    }
}

5.5 死锁

当两个线程相互等待对方释放同步监视器就会发生死锁。

6 线程通信

6.1 线程的协调运行

Object类提供的wait(), notify(),notifyAll()三个方法,必须由同步监视器来调用:

  • 对于使用synchronized修饰的同步方法,该类的默认实例this就是同步监视器
  • 对于使用synchronized修饰的代码块,后面括号里的对象就是同步监视器

6.2 使用条件变量进行控制协调

如果程序不使用synchronized关键字来保持同步,而是直接使用Lock对象来保持同步,则系统中不存在隐式的同步监视器对象。Java提供了一个Condition类来保持协调。

  • await()
  • signal()
  • signalAll()
public class Account
{
    private final Lock lock = new ReentrantLock();
    private final Condition cond = lock.newCondition();

####6.3 使用管道流
如果两条线程之间需要更多的信息交互,则可以考虑使用管道流。

PipedWriter pw = null;
PipedReader pr = null;
try
{
pw = new PipedWriter();
pr = new PipedReader();
pw.connect(pr);
new WriterThread(pw).start();
new ReaderThread(pr).start();
}

###7 Callable和Future
Callable看起来像是Runnable的接口和增强版,call方法是其线程执行体,但是比run()方法更强大:可以有返回值,可以抛出异常

class RtnThread implements Callable<Integer>
{
public Integer call(){
return i
}
}
public class CallableTest
{
public static void main(String[] args)
{
RtnThread rt = new RtnThread();
FutrueTask<Integer> task = new FutureTask<Integer>(rt);
new Thread(task,'name').start();
System.out.println(task.get());
}
}


###8 线程池
略过

###9 线程相关类
####9.1 ThreadLocal类
ThreadLocal类是线程局部变量的意思,就是为每一个使用该变量的线程都提供一个变量值的副本。从而避免冲突。
ThreadLocal提供了三个public方法:
* T get()
* void remove()
* void set(T value)
>如果需要进行多个线程之间的资源共享,就需要使用同步机制,如果只是需要隔离多个线程之间的共享冲突,则可以使用ThreadLocal

####9.2 线程包装不安全的集合
Java集合中介绍的ArrayList,LinkedList, HashSet, TreeSet, HashMap都是线性不安全的。可以使用Collections的方法来将其变成线程安全:
SynchronizedCollection/List/Map/Set/SortedMap/SortedSet

####9.3 线程安全的集合类
JDK1.5开始,java.util.concurrent包下提供了ConcurrentHashMap, ConcurrentLinkedQueue。

相关文章

  • 作业2

    013-每特教育&蚂蚁课堂-第七期-从零开始学习多线程技术-多线程技术快速入门 什么是多线程 进程与线程的区别 多...

  • 七、多线程

    一、线程概述 线程是在程序中独立并发的执行流,相比于进程,线程具有更高的性能,多个线程可以共享一个进程虚拟空间,线...

  • 《码出高效-Java开发手册》读书笔记 第七章(一)

    第七章题目是“并发与多线程”,在实际Android开发中,多线程编程是无法避免的,这次跟着书籍来学习下Java里的...

  • java并发编程(七)

    java多线程编程(七) 这一节,看一下重排序对多线程的影响。 示例代码: flag 变量是个标记,用来标记变量a...

  • PHP七彩云转码CMS系统源码

    PHP七彩云转码CMS系统源码,非常实用的视频切片、云盘转码服务系统 更新日志1、增加多线程转码(使用多线程转码提...

  • JAVA面试汇总(二)多线程(六)

    JAVA多线程内容比较多,今天写完了第六篇,后边还有七(肯定最后一篇了)。 如何保证多线程读写文件的安全?(1)读...

  • 多线程编程(七) 多线程实践

    背景/简介 线程和进程 线程和Python thread 模块 threading模块 单线程和多线程对比 多线程...

  • JAVA面试汇总(三)集合(一)

    JAVA多线程七篇终于写完了,今天开始了新的JAVA面试汇总,集合部分,这部分其实比多线程有意思多了,这个计划最多...

  • 主题七《多线程》

    1、概念 进程:正在运行的一个应用程序线程:在进程中真正执行任务的关系:包含(进程中至少有一条线程)串行:针对一个...

  • 多线程基础(七)

    多线程常见面试题 1. 多线程有几种实现方案,分别是哪几种? 两种(对线程池那块比较熟悉可以答三种)。继承Thre...

网友评论

      本文标题:七、多线程

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