多线程一直Java开发中的难点,也是面试中的常客,趁着还有时间,打算巩固一下JUC方面知识,我想机会随处可见,但始终都是留给有准备的人的,希望我们都能加油!!!

沉下去,再浮上来,我想我们会变的不一样的。

一、JUC简介

JUC实际上就是我们对于jdk中java.util .concurrent 工具包的简称。这个包下都是Java处理线程相关的类,自jdk1.5后出现。

二、进程与线程

2.1、进程

概述:

进程(Process) 是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础。 在当代面向线程设计的计算机结构中,进程是线程的容器程序是指令、数据及其组织形式的 描述进程是程序的实体

定义:

狭义定义:进程是正在运行的程序的实例(an instance of a computer program that is being executed)。

广义定义:进程是一个具有一定独立功能的程序关于某个数据集合的一次运行活动。它是操作系统动态执行的基本单元,在传统的操作系统中,进程既是基本的分配单元,也是基本的执行单元。

2.2、线程

线程(thread) 是操作系统能够进行运算调度的最小单位。它被包含在进程之 中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流, 一个进程中可以并发多个线程,每条线程并行执行不同的任务

1、线程是独立调度和分派的基本单位。2、同一进程中的多条线程将共享该进程中的全部系统资源。3、一个进程可以有很多线程,每条线程并行执行不同的任务。可并发执行。

当然,我们Java都知道的线程的同步是Java多线程编程的难点,因为要给哪些地方是共享资源(竞争资源),什么时候要考虑同步等,都是编程中的难点。所以才有了那么多滴锁,看到烦人。

2.3、创建线程的三种常见方式

  1. 通过实现Runnable接口来创建Thread线程
public class TheardCreateDemo {

    public static void main(String[] args) {
Runnable runnable = new SomeRunnable();
Thread thread1 = new Thread(runnable);
thread1.start();
//lamda表达式方式
Thread thread2 = new Thread(() -> {
System.out.println("使用lamda表达式方式");
});
thread2.start();
}
}
class SomeRunnable implements Runnable
{
@Override
public void run()
{
System.out.println(Thread.currentThread().getName()+":: 通过实现Runnable接口来创建Thread线程");
}
}

2.通过继承Thread类来创建一个线程

public class TheardCreateDemo {

    public static void main(String[] args) {
SomeThread thread = new SomeThread();
thread.start();
}
} class SomeThread extends Thread{
@Override
public void run() {
System.out.println("通过继承Thread类来创建一个线程");
}
}

3.通过实现Callable接口来创建Thread线程

public class TheardCreateDemo {

    public static void main(String[] args) throws ExecutionException, InterruptedException {

        FutureTask<Object> futureTask = new FutureTask<Object>(new SomeCallable<Object>());
Thread oneThread = new Thread(futureTask); oneThread.start();
// 这里可以在运行之后获得 返回值
System.out.println(futureTask.get());
}
} class SomeCallable<Object> implements Callable<Object> {
@Override
public Object call() throws Exception {
System.out.println("通过实现Callable接口来创建Thread线程");
// 这个是可以返回数据的 这里就随便返回个 1024 哈
return (Object)" 这个是可以返回数据的 这里就随便返回个哈";
}
}

这里之后有篇文章还会讲到这个点的。

这里稍微讲下步骤:

}

步骤1:创建实现Callable接口的类SomeCallable

步骤2:创建一个类对象:Callable oneCallable = new SomeCallable();

步骤3:由Callable创建一个FutureTask对象:

FutureTask futureTask= new FutureTask(oneCallable);

注释:FutureTask是一个包装器,它通过接受Callable来创建,它同时实现了Future和Runnable接口。

步骤4:由FutureTask创建一个Thread对象:Thread oneThread = new Thread(futureTask);

步骤5:启动线程:oneThread.start();

这里为什么Thread(FutureTask futureTask)可以勒?

Thread的构造函数:

public Thread(Runnable target) {
this(null, target, "Thread-" + nextThreadNum(), 0);
}

原因:因为套娃套到一起啦。

public class FutureTask<V> implements RunnableFuture<V> 

public interface RunnableFuture<V> extends Runnable, Future<V>

线程池的创建方式之后有一章会讲到,就不在此处增加篇幅啦。

三、并发和并行

在了解并发和并行之前,让我们先来看一看串行是什么样的吧。

1)串行模式:

串行模式:即表示所有任务都是按先后顺序进行。串行是一次只能取的一个任务,并执行这个任务。

举个生活中的小例子:就是在火车站买票,今天只开放这一个窗口卖票,那么我们只有等到前面的人都买了,才能轮到我们去买。即按先后顺序买到票。

2)并行模式:

概述:一组程序按独立异步的速度执行,无论从微观还是宏观,程序都是一起执行的。对比地,并发是指:在同一个时间段内,两个或多个程序执行,有时间上的重叠(宏观上是同时,微观上仍是顺序执行)。

并行模式:并行意味着可以同时取得多个任务,并同时去执行所取得的这些任务。

我们还是用上面那个例子:还是在买票,以前是只有一个窗口卖票,但是近几年发展起来了,现在有五个窗口卖票啦,大大缩短了人们买票的时间。

并行模式相当于将长长的一条队列,划分成了多条短队列,所以并行缩短了任务队列的长度。不过并行的效率,一方面受多进程/线程编码的好坏的影响,另一方面也受硬件角度上的CPU的影响。

3)并发:

并发并发指的是多个程序可以同时运行的一种现象,并发的重点在于它是一种现象,并发描述的是多进程同时运行的现象。但真正意义上,一个单核心CPU任一时刻都只能运行一个线程。所以此处的"同时运行"表示的不是真的同一时刻有多个线程运行的现象(这是并行的概念),而是提供了一种功能让用户看来多个程序同时运行起来了,但实际上这些程序中的进程不是一直霸占 CPU 的,而是根据CPU的调度,执行一会儿停一会儿。

4)小小的总结一下:

并发:即同一时刻多个线程在访问同一个资源,多个线程对一个点

  • 例子:秒杀活动、12306抢回家的票啦、抢演唱会的票...

并行:多个任务一起执行,之后再汇总

  • 例子:电饭煲煮饭、用锅炒菜,两个事情一起进行,(最后我们一起干饭啦干饭啦)

四、用户线程和守护线程

用户线程:指不需要内核支持而在用户程序中实现的线程,其不依赖于操作系统核心,应用进程利用线程库提供创建、同步、调度和管理线程的函数来控制用户线程。

守护线程是指在程序运行的时候在后台提供一种通用服务的线程,用来服务于用户线程;不需要上层逻辑介入,当然我们也可以手动创建一个守护线程。(用白话来说:就是守护着用户线程,当用户线程死亡,守护线程也会随之死亡)

比如垃圾回收线程就是一个很称职的守护者,并且这种线程并不属于程序中不可或缺的部分。因此,当所有的非守护线程结束时,程序也就终止了,同时会杀死进程中的所有守护线程。反过来说,只要任何非守护线程还在运行,程序就不会终止。

用一个简单代码来模拟一下:

未设置为守护线程时:主线程执行完成了,但是我们自己创建的线程仍然未结束。

设置为守护线程后:明显可以看到,当主线程执行完成后,我们设置为守护线程的那个线程也被强制结束了。

setDaemon就是设置为是否为守护线程。

五、自言自语

最近又开始了JUC的学习,感觉Java内容真的很多,但是为了能够走的更远,还是觉得应该需要打牢一下基础。

最近在持续更新中,如果你觉得对你有所帮助,也感兴趣的话,关注我吧,让我们一起学习,一起讨论吧。

你好,我是博主宁在春,Java学习路上的一颗小小的种子,也希望有一天能扎根长成苍天大树。

希望与君共勉

待我们,别时相见时,都已有所成

你知道什么是JUC了吗?的更多相关文章

  1. Java多线程系列--“JUC锁”03之 公平锁(一)

    概要 本章对“公平锁”的获取锁机制进行介绍(本文的公平锁指的是互斥锁的公平锁),内容包括:基本概念ReentrantLock数据结构参考代码获取公平锁(基于JDK1.7.0_40)一. tryAcqu ...

  2. Java多线程系列--“JUC锁”04之 公平锁(二)

    概要 前面一章,我们学习了“公平锁”获取锁的详细流程:这里,我们再来看看“公平锁”释放锁的过程.内容包括:参考代码释放公平锁(基于JDK1.7.0_40) “公平锁”的获取过程请参考“Java多线程系 ...

  3. 【目录】JUC锁框架目录

    JUC锁框架的目录整理如下: 1. [JUC]JUC锁框架综述 2. [JUC]JDK1.8源码分析之LockSupport(一) 3. [JUC]JDK1.8源码分析之AbstractQueuedS ...

  4. 【目录】JUC集合框架目录

    JUC集合框架的目录整理如下: 1. [JUC]JUC集合框架综述 2. [JUC]JDK1.8源码分析之ConcurrentHashMap(一) 3. [JUC]JDK1.8源码分析之Concurr ...

  5. java多线程系类:JUC原子类:01之框架

    本系列内容全部来自于http://www.cnblogs.com/skywang12345/p/3514589.html 特在此说明!!!!! 根据修改的数据类型,可以将JUC包中的原子操作类可以分为 ...

  6. Java多线程系列--“JUC锁”10之 CyclicBarrier原理和示例

    概要 本章介绍JUC包中的CyclicBarrier锁.内容包括:CyclicBarrier简介CyclicBarrier数据结构CyclicBarrier源码分析(基于JDK1.7.0_40)Cyc ...

  7. Java多线程系列--“JUC锁”02之 互斥锁ReentrantLock

    本章对ReentrantLock包进行基本介绍,这一章主要对ReentrantLock进行概括性的介绍,内容包括:ReentrantLock介绍ReentrantLock函数列表ReentrantLo ...

  8. Java多线程系列--“JUC锁”01之 框架

    本章,我们介绍锁的架构:后面的章节将会对它们逐个进行分析介绍.目录如下:01. Java多线程系列--“JUC锁”01之 框架02. Java多线程系列--“JUC锁”02之 互斥锁Reentrant ...

  9. 【JUC】JUC锁框架综述

    一.前言 在分析完了集合框架后,很有必要接着分析java并发包下面的源码,JUC(java.util.concurrent)源码也是我们学习Java迈进一步的重要过程.我们分为几个模块进行分析,首先是 ...

  10. 【JUC】JUC集合框架综述

    一.前言 完成了JUC的锁框架的分析后,现在分析JUC集合框架,之前分析过的集合框架,很大程度上都不是线程安全的,其在多线程环境下会出现很多问题,为了保证在多线程环境下仍然能够正确安全的访问集合,出现 ...

随机推荐

  1. 剑指 Offer 14- II. 剪绳子 II

    剑指 Offer 14- II. 剪绳子 II 给你一根长度为 n 的绳子,请把绳子剪成整数长度的 m 段(m.n都是整数,n>1并且m>1),每段绳子的长度记为 k[0],k[1]... ...

  2. Tars | 第5篇 基于TarsGo Subset路由规则的Java JDK实现方式(上)

    目录 前言 1. 修改.tars协议文件 1.1 Go语言修改部分 1.2 修改地方的逻辑 1.3 通过协议文件自动生成代码 2. [核心]增添Subset核心功能 2.1 Go语言修改部分 2.2 ...

  3. npm配置镜像及nrm使用

    ​ 淘宝npm镜像 搜索地址:http://npm.taobao.org/ registry地址:http://registry.npm.taobao.org/ cnpmjs镜像 搜索地址:http: ...

  4. dubbo 2.7应用级服务发现踩坑小记

    本文已收录 https://github.com/lkxiaolou/lkxiaolou 欢迎star. 背景 本文记录最近一位读者反馈的dubbo 2.7.x中应用级服务发现的问题,关于dubbo应 ...

  5. shell--目录通配符

    符号 说明 ? 匹配任一字符 * 匹配一个或多个字符 [a-z0-9] 类似于正则表达式, 若想匹配?可用[?] [!a-z] 类似于正则表达式[^a-z], 不匹配中括号中的内容 {string1, ...

  6. Linux下运行bash脚本显示“: /usr/bin/env: "bash\r": 没有那个文件或目录

    用 ./ 运行bash脚本文件出现 报错信息 /usr/bin/env: "bash\r": 没有那个文件或目录 错误原因:这主要是因为bash后面多了\r这个字符的原因.在lin ...

  7. sed 找出含有某个字符串的行 注释掉

    1.源文件例子 [root@node1 ~]# cat /etc/fstab # # /etc/fstab # Created by anaconda on Mon Mar 1 18:32:15 20 ...

  8. elementUI 表格 table 的表头错乱问题

    页面中多组件开发时,如果页面中有表格的,table表格头出现表头错乱 // 全局设置1 body .el-table th.gutter{ 2 display: table-cell!importan ...

  9. 洛谷P1088——火星人(全排列+数学模拟)

    题目描述 人类终于登上了火星的土地并且见到了神秘的火星人.人类和火星人都无法理解对方的语言,但是我们的科学家发明了一种用数字交流的方法.这种交流方法是这样的,首先,火星人把一个非常大的数字告诉人类科学 ...

  10. 一起学习PHP中GD库的使用(三)

    上篇文章我们已经学习了一个 GD 库的应用,那就是非常常用的制作验证码的功能.不过在现实的业务开发中,这种简单的验证码已经使用得不多了,大家会制作出更加复杂的验证码来使用.毕竟现在的各种外挂软件已经能 ...