Java教程

Java 核心技术卷1 --第十四章 并发

本文主要是介绍Java 核心技术卷1 --第十四章 并发,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

Github代码链接: https://github.com/deyou123/corejava.git

第十四章 并发

  • 每一个任务称为一个线程;是线程控制的简称;
  • 多线程程序:同时运行一个以上线程的程序。
  • 每个进程拥有自己的一整套变量;而线程则共享数据;
  • 共享变量使线程之间的通信比进程之间的通信更有效、更容易;线程比进程更“轻量级”,线程的创建和撤销开销小。

14.1 什么是线程

14.1.1 使用线程给其他任务提供机会

public interface Runnable
{
	void run();
}

Runnable r = ()->{task code};
Thread t = new Thread(r);
t.start();

14.2 中断线程

Runnable r= ()-> {
try
{
	while (!Thread.currentThread().islnterrupted0 && morework todo)
	{
	do more work
	}
}
catch(InterruptedException e)
{
// thread was interr叩ted during sleep or wait
}
finally
{
	cleanup,ifrequired
}
// exiting the run method terminates the thread
} ;

14.3 线程状态

线程可以有如下6 种状态:

  • New (新创建)
  • Runnable (可运行)
  • Blocked ( 被阻塞)
  • Waiting (等待)
  • Timed waiting (计时等待)
  • Terminated ( 被终止)

在这里插入图片描述

14.3.1 新建线程

new Thread®; 线程还没开始运行;

14.3.2 可运行线程

  • 一旦调用start方法,线程处于 runnable状态;
  • 可能正在运行; 也可能没有运行;

14.3.3 被阻塞线程和等待线程

暂时不活动;不运行任何代码且消耗最小资源;

  • 一个线程试图获取一个内部的对象琐,该琐被其他线程所持有,该线程进入阻塞状态;当所有其他线程释放该琐,并且线程调度器允许本线程持有他,该线程变成非阻塞状态;
  • 当线程等待另一个线程通知调度器一个条件时,他进入等待状态;
  • 有几个方法有一个超时参数。调用他们呆滞线程进入计时等待状态(timed waiting,状态将一直保持到超时期满或者接收到适当的通知。
    超时参数的方法有:Thread.sleep、Object.wait、Thread.join、Lock.tryLock和Condition.await;

14.3.4 被终止的线程

两个原因:

  • run方法正常退出而自然死亡;
  • 因为一个没有捕获的异常终止了run方法而意外死亡;

14.4 线程属性

14.4.1 线程优先级

  • 每个线程又有个优先级;

  • 默认情况,一个线程继承它父线程的优先级;

  • setPriority方法提高或降低线程的优先级

  • 优先级设置为MIN_PRIORITY和MAX_PRIORITY之间的任何值。NORM_PRIORITY被定义为5;

  • 线程调度器优先选择较高优先级线程;

  • 线程优先级高度依赖于系统;

14.4.2 守护线程

  • t.setDaemon(true);
    将线程转换为守护线程(daemon thread)
  • 唯一用途:为其他线程提供服务;
  • 计时器,定时发送“计时器滴答”信号给其他线程;或清空过时的高速缓存项的线程;
  • 只剩下守护线程时,虚拟机就推出了;
  • 守护线程应该永远不去访问固有资源,如文件、数据库等; 它会在任何时候升值在一个操作的中间发生中断;

14.4.3 未捕获异常处理器

  • 处理器必须属于一个实现 Thread.UncaughtExceptionHandler接口的类;
    void uncaughtException(Thread t, Throwable e);
  • 可以用setUncaughtExceptionHandler方法为任何线程安装一个处理器;
  • 也可以用Thread类的静态方法 setDefaultUncaughtExceptionHandler 为所有线程安装一个默认的处理器;
  • 默认的处理器为空;此时的处理器就是该线程的ThreadGroup对象;

uncaughtException方法做如下操作:
1、如果该线程组有父线程组,那么父线程组的uncaughtException方法被调用;
2、否则,如果Thread.getDefaultExceptionHandler方法返回一个非空的处理器,则调用该处理器。
3、否则,如果Throwable是ThreadDeath的一个实例,什么都不做
4、否则,线程的名字以及Throwable的战轨迹被输出到System.err上。

14.5 同步

两个或两个以上的

14.6 阻塞队列

  • 多线程问题,可以通过使用一个或多个队列以优雅且安全的方式将其形式化。
    生产者线程向队列插入元素,消费者线程取出他们。
  • 使用队列,可以安全的从一个线程向另一个线程传递数据。
    将指令对象插入队列,另一个线程从队列取出指令执行转账;只有该线程可以访问银行对象的内部,因此不需要同步。

阻塞队列:试图向队列添加元素而队列已满,或是想从队列移除元素而队列为空的时候,导致线程阻塞。
多线程合作:工作者线程可以周期性的将中间结果放在阻塞队列;其他的工作者线程移出中间结果并进一步加以修改。

  • 队列会自动地平衡负载,互相等待。

在这里插入图片描述
阻塞队列分为3类,取决于当队列满或空时他们的响应方式。

  • 当队列当作县城管理工具来使用,用put和take方法。
  • 当试图向满地队列中添加或从空的队列中移除元素时,add、remove、element操作抛出异常。
  • 一个多线程程序中,队列会在任何时候满或空,一定要用offer、poll、peek方法做替代。

注释
因为poll、peek返回空代表失败,向队列插入null值是非法的。

  • 带超时地offer方法和poll方法地变体:
    • boolean success = q.offer(x, 100, TimeUnit.MILLISECONDS);
      100毫秒内在队列尾部插入一个元素,成功true;否则超时,false;

    • Object head = q.poll(100, TimeUnit.MILLISECONDS);

14.7 线程安全的集合

14.7.1 高效地映射、集合队列

java.util.concurrent提供: ConcurrentHashMap、ConcurrentSkipListMap、ConcurrentSkipListSet和ConcurrentLinkedQueue。

14.8 Callable与Future

14.9 执行器

14.10 同步器

14.11 线程与Swing

这篇关于Java 核心技术卷1 --第十四章 并发的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!