美文网首页
多线程并发编程概念理解

多线程并发编程概念理解

作者: 杰子他爸 | 来源:发表于2019-05-28 14:27 被阅读0次

线程与进程

线程的实现

1、继承Thread类,通过start()方法去启动线程。注意,不是调用run()方法启动线程,run方法中只是定义需要执行的任务,如果调用run方法,即相当于在主线程中执行run方法,跟普通的方法调用没有任何区别,此时并不会创建一个新的线程来执行定义的任务。

2、实现Runnable接口

使用ExecutorService、Callable、Future实现有返回结果的多线程,这里只做备注。

Executors类,提供了一系列工厂方法用于创先线程池,返回的线程池都实现了ExecutorService接口。

public static ExecutorService newFixedThreadPool(int nThreads)

创建固定数目线程的线程池。

public static ExecutorService newCachedThreadPool()

创建一个可缓存的线程池,调用execute 将重用以前构造的线程(如果线程可用)。如果现有线程没有可用的,则创建一个新线程并添加到池中。终止并从缓存中移除那些已有 60 秒钟未被使用的线程。

public static ExecutorService newSingleThreadExecutor()

创建一个单线程化的Executor。

public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize)

创建一个支持定时及周期性的任务执行的线程池,多数情况下可用来替代Timer类。

ExecutoreService提供了submit()方法,传递一个Callable,或Runnable,返回Future。如果Executor后台线程池还没有完成Callable的计算,这调用返回Future对象的get()方法,会阻塞直到计算完成。

线程的状态

创建(new)状态: 准备好了一个多线程的对象

就绪(runnable)状态: 调用了start()方法, 等待CPU进行调度

运行(running)状态: 执行run()方法

阻塞(blocked)状态: 暂时停止执行, 可能将资源交给其它线程使用

终止(dead)状态: 线程销毁

在有些教程上将blocked、waiting、time waiting统称为阻塞状态,这个也是可以的,只不过这里我想将线程的状态和Java中的方法调用联系起来,所以将waiting和time waiting两个状态分离出来。

注:sleep和wait的区别:

sleep是Thread类的方法,wait是Object类中定义的方法.

Thread.sleep不会导致锁行为的改变, 如果当前线程是拥有锁的, 那么Thread.sleep不会让线程释放锁.

Thread.sleep和Object.wait都会暂停当前的线程. OS会将执行时间分配给其它线程. 区别是, 调用wait后, 需要别的线程执行notify/notifyAll才能够重新获得CPU执行时间.

sleep()方法

sleep相当于让线程睡眠,交出CPU,让CPU去执行其他的任务。

但是有一点要非常注意,sleep方法不会释放锁,也就是说如果当前线程持有对某个对象的锁,则即使调用sleep方法,其他线程也无法访问这个对象。

从上面输出结果可以看出,当Thread-0进入睡眠状态之后,Thread-1并没有去执行具体的任务。只有当Thread-0执行完之后,此时Thread-0释放了对象锁,Thread-1才开始执行。

注意,如果调用了sleep方法,必须捕获InterruptedException异常或者将该异常向上层抛出。当线程睡眠时间满后,不一定会立即得到执行,因为此时可能CPU正在执行其他的任务。所以说调用sleep方法相当于让线程进入阻塞状态

yield()方法

调用yield方法会让当前线程交出CPU权限,让CPU去执行其他的线程。它跟sleep方法类似,同样不会释放锁。但是yield不能控制具体的交出CPU的时间,另外,yield方法只能让拥有相同优先级的线程有获取CPU执行时间的机会。

注意,调用yield方法并不会让线程进入阻塞状态,而是让线程重回就绪状态,它只需要等待重新获取CPU执行时间,这一点是和sleep方法不一样的。

join()方法

在很多情况下,主线程创建并启动了线程,如果子线程中药进行大量耗时运算,主线程往往将早于子线程结束之前结束。这时,如果主线程想等待子线程执行完成之后再结束,比如子线程处理一个数据,主线程要取得这个数据中的值,就要用到join()方法了。方法join()的作用是等待线程对象销毁。

setDaemon和isDaemon

用来设置线程是否成为守护线程和判断线程是否是守护线程。

守护线程和用户线程的区别在于:守护线程依赖于创建它的线程,而用户线程则不依赖。举个简单的例子:如果在main线程中创建了一个守护线程,当main方法运行完毕之后,守护线程也会随着消亡。而用户线程则不会,用户线程会一直运行直到其运行完毕。在JVM中,像垃圾收集器线程就是守护线程。

停止线程

停止线程是在多线程开发时很重要的技术点,掌握此技术可以对线程的停止进行有效的处理。

停止一个线程可以使用Thread.stop()方法,但最好不用它。该方法是不安全的,已被弃用。

在Java中有以下3种方法可以终止正在运行的线程:

使用退出标志,使线程正常退出,也就是当run方法完成后线程终止

使用stop方法强行终止线程,但是不推荐使用这个方法,因为stop和suspend及resume一样,都是作废过期的方法,使用他们可能产生不可预料的结果。

使用interrupt方法中断线程,但这个不会终止一个正在运行的线程,还需要加入一个判断才可以完成线程的停止。

相关文章

  • 多线程并发编程概念理解

    线程与进程 线程的实现 1、继承Thread类,通过start()方法去启动线程。注意,不是调用run()方法启动...

  • Java并发编程知识点梳理

    一 并发编程基础知识 1.1 概念 并发编程是你编写的代码有可能在多线程环境中执行, 1.2 为什么要用并发编程...

  • 带你搞懂Java多线程(一)

    什么是多线程 多线程也叫并发编程,那么在写多线程之前,我们先来了解一下并发编程的基础概念。①CPU核心数和线程数的...

  • Thread的生命周期

    前言 线程是java开发的核心概念。不理解线程的生命周期是无法理解并发和多线程编程的。下面我会以状态机的形式介绍一...

  • java并发编程(一)

    并发编程比较重要的概念有哪些? 一:什么是单核多线程和多核多线程? 1:单核多线程指的是单核CPU轮流执行多个线程...

  • python中的多线程与并发

    引子:经常听别人说起并发这个概念,在python语言中怎么理解多线程,多线程和并发是什么关系,什么时候更适合选择多...

  • synchronized和monitor使用案例

    多线程编程是开发高并发应用的重点和难点,是许多互联网公司面试环节必不可少的部分.打算围绕多线程编程总结一些核心概念...

  • Reentrantlock和Condition使用案例

    多线程编程是开发高并发应用的重点和难点,是许多互联网公司面试环节必不可少的部分.打算围绕多线程编程总结一些核心概念...

  • CountDownLatch使用案例

    多线程编程是开发高并发应用的重点和难点,是许多互联网公司面试环节必不可少的部分.打算围绕多线程编程总结一些核心概念...

  • CyclicBarrier使用案例

    多线程编程是开发高并发应用的重点和难点,是许多互联网公司面试环节必不可少的部分.打算围绕多线程编程总结一些核心概念...

网友评论

      本文标题:多线程并发编程概念理解

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