线程

2018-03-16  本文已影响0人  F野鸽子

如何创建和使用线程

  1. 继承 Thread 类。
  2. 实现 Runnable 接口。
  3. 使用 Callable 和 Future 创建线程。

实现 Runnable 和 Callable 接口的优缺点

优点:

缺点:

采用继承 Thread 类的方式创建多线程的优缺点

优点:

缺点:

线程的生命周期

新建(New),就绪(Runnable),运行(Running),阻塞(Blocked),死亡(Dead)。

  1. 程序调用 sleep() 方法主动放弃所占有的处理器资源,该线程被阻塞。|sleep 过了指定时间,进入就绪。
  2. 程序调用了一个阻塞式 IO 方法,在该方法返回之前,该线程被阻塞。|方法已经返回,进入就绪。
  3. 线程试图获得一个同步监视器,但该同步监视器被其他线程所持有。|线程成功获得了同步监视器,进入就绪。
  4. 线程在等待某个 notify。| 其他线程发出了 notify。
  5. 程序调用了线程的 suspend() 方法将线程挂起。此方法很容易导致思索,尽量避免使用。 | 该线程调用了 resume() 恢复方法。

被阻塞的线程会在合适的时候转变为就绪状态,而不是运行状态。被阻塞线程的阻塞解除后,必须重新等待线程调度器再次调度它。

  1. run() 或者 call() 方法执行结束,结束后线程处于死亡状态。
  2. 线程直接抛出一个未捕获的 Exception 或 Error。
  3. 直接调用线程的 stop() 方法来结束该线程,此方法容易导致死锁,不建议使用。

控制线程

Join 线程

后台线程(Daemon Thread)

为其他线程提供服务的线程叫做后台线程,又称为“守护线程”或“精灵线程”。例如,JVM 的垃圾回收线程就是典型的后台线程。
特点:所有的前台线程都死亡,后台线程会自动死亡。
调用 Thread.setDeamon(true) 方法可将指定线程设置为后台线程。必须在 start() 方法之前调用。

线程睡眠(Sleep)

sleep(long millis),让当前正在执行的线程暂停 millis 毫秒,并进入阻塞状态,该方法收到系统计时器和线程调度器的精度与准确度的影响。

线程让步(Yield)

也可以让当前正在执行的线程暂停,但不会阻塞该线程,只是将线程转到就绪状态。

sleep 和 yield 的区别:

改变线程的优先级

Thread 提供了三个常量如下:

/**
 * The minimum priority that a thread can have.
 */
public final static int MIN_PRIORITY = 1;

/**
 * The default priority that is assigned to a thread.
 */
public final static int NORM_PRIORITY = 5;

/**
 * The maximum priority that a thread can have.
 */
public final static int MAX_PRIORITY = 10;

线程同步

同步代码块

synchronized(obj){
//这就是同步代码块
}

目的:阻止两个线程对同一个共享资源进行并发访问,因此通常推荐使用可能被并发的共享资源充当同步监视器

线程开始执行同步代码块之前,必须先获得对同步监视器的锁定,当同步代码块执行完成后,该线程会释放对该同步监视器的锁定。

案例:package com.dzzchao.thread.sync; 包中代码。

同步方法

同步方法就是用 synchronize 来修饰一个方法,则该方法为同步方法,无需显示指定同步监视器,同步方法的同步监视器是this,也就是调用该方法的对象。

案例:package com.dzzchao.thread.sync2; 包中代码。

通过同步方法可以实现线程安全的类,线程安全的类特征如下:

synchronized 可以修饰方法,可以修饰代码块,但不能修饰构造器,成员变量。

释放同步监视器的锁定

会释放:

同步锁

ReentrantLock

案例: package com.dzzchao.thread.ReentrantLock; 包中代码。

死锁

案例: package com.dzzchao.thread.Dead; 包中代码。

线程通信

传统的线程通信

使用 Object 类提供的 wait(),notify(),notifyAll() 三个方法,

方法解释:

案例:package com.dzzchao.thread.notify 包下代码。

使用 Condition 控制线程通信

如果程序不适用 synchronized 关键字来保持同步,而是直接用 lock 对象来保证同步,则系统中不存在隐式的同步监视器,也就不能使用传统的线程通信方法了。

Condition

使用阻塞队列(BlockingQueue)控制线程通信

BlockingQueue 的实现类

线程组和未处理的异常

线程池

ThreadPoolExecutor (int corePoolSize,
                int maximumPoolSize,
                long keepAliveTime,
                TimeUnit unit,
                BlockingQueue<Runnable> workQueue)

Parameters

线程池的分类

//使用举例
ExecutorService executorService = Executors.newCachedThreadPool();

线程相关类

代码示例地址请点我

To be continued...

上一篇下一篇

猜你喜欢

热点阅读