
多线程
文章平均质量分 64
赵鹏翔
上海市东华大学在读研究生,大家共勉。
展开
-
Java对象的创建过程
Java对象的创建过程①类加载检查虚拟机遇到一条 new 指令时,首先将去检查这个指令的参数是否能在常量池中定位到这个类的符号引用,并且检查这个符号引用代表的类是否已被加载过、解析和初始化过。如果没有,那必须先执行相应的类加载过程。②分配内存在类加载检查通过后,接下来虚拟机将为新生对象分配内存。对象所需的内存大小在类加载完成后便可确定,为对象分配空间的任务等同于把一块确定大小的内存从 Java 堆中划分出来。分配方式有 “指针碰撞” 和 “空闲列表” 两种,选择那种分配方式由 Java 堆是否规整原创 2021-04-22 13:40:17 · 483 阅读 · 0 评论 -
线程池详解
1. 为什么要用线程池?线程池、数据库连接池、Http 连接池等等都是对池化技术思想的应用。池化技术的思想主要是为了减少每次获取资源的消耗,提高对资源的利用率。线程池提供了一种限制和管理资源(包括执行一个任务)。 每个线程池还维护一些基本统计信息,例如已完成任务的数量。使用线程池的好处:1降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁造成的消耗。2提高响应速度。当任务到达时,任务可以不需要的等到线程创建就能立即执行。3提高线程的可管理性。线程是稀缺资源,如果无限制的创建,不仅会消耗系统原创 2021-04-21 23:25:57 · 276 阅读 · 0 评论 -
ThreadLocal处理线程私有数据
1. ThreadLocal简介通常情况下,我们创建的变量是可以被任何一个线程访问并修改的。如果想实现每一个线程都有自己的专属本地变量该如何解决呢? JDK中提供的 ThreadLocal 类正是为了解决这样的问题。ThreadLocal 类主要解决的就是让每个线程绑定自己的值,可以将 ThreadLocal 类形象的比喻成存放数据的盒子,盒子中可以存储每个线程的私有数据。如果你创建了一个 ThreadLocal 变量,那么访问这个变量的每个线程都会有这个变量的本地副本,这也是 ThreadLocal原创 2021-04-21 22:49:15 · 721 阅读 · 1 评论 -
synchronized 关键字和 volatile 关键字的区别
volatile 关键字的主要作用1 保证变量的可见性在 JDK1.2 之前,Java的内存模型实现总是从主存(即共享内存)读取变量,是不需要进行特别的注意的。而在当前的 Java 内存模型下,线程可以把变量保存本地内存(比如机器的寄存器)中,而不是直接在主存中进行读写。这就可能造成一个线程在主存中修改了一个变量的值,而另外一个线程还继续使用它在寄存器中的变量值的拷贝,造成数据的不一致。要解决这个问题,就需要把变量声明为volatile,这就指示 JVM,这个变量是不稳定的,每次使用它都到主存中进行原创 2021-04-21 20:08:49 · 227 阅读 · 0 评论 -
并发编程的三个重要特性
并发编程的三个重要特性1.原子性 : 一个的操作或者多次操作,要么所有的操作全部都得到执行并且不会收到任何因素的干扰而中断,要么所有的操作都执行,要么都不执行。 synchronized 可以保证代码片段的原子性。2.可见性 :当一个变量对共享变量进行了修改,那么另外的线程都是立即可以看到修改后的最新值。 volatile 关键字可以保证共享变量的可见性。3.有序性 :代码在执行的过程中的先后顺序,Java 在编译器以及运行期间的优化,代码的执行顺序未必就是编写代码时候的顺序。 volatile 关键原创 2021-04-21 20:07:43 · 545 阅读 · 0 评论 -
synchronized和ReentrantLock 的区别
synchronized和ReentrantLock 的区别① 两者都是可重入锁两者都是可重入锁。“可重入锁”概念是:自己可以再次获取自己的内部锁。比如一个线程获得了某个对象的锁,此时这个对象锁还没有释放,当其再次想要获取这个对象的锁的时候还是可以获取的,如果不可锁重入的话,就会造成死锁。同一个线程每次获取锁,锁的计数器都自增1,所以要等到锁的计数器下降为0时才能释放锁。②synchronized 依赖于 JVM 而 ReentrantLock 依赖于 APIsynchronized 是依赖于 JV原创 2021-04-21 19:31:43 · 318 阅读 · 0 评论 -
synchronized 关键字 整理
synchronized 关键字synchronized关键字解决的是多个线程之间访问资源的同步性,synchronized关键字可以保证被它修饰的方法或者代码块在任意时刻只能有一个线程执行。另外,在 Java 早期版本中,synchronized属于重量级锁,效率低下,因为监视器锁(monitor)是依赖于底层的操作系统的 Mutex Lock 来实现的,Java 的线程是映射到操作系统的原生线程之上的。如果要挂起或者唤醒一个线程,都需要操作系统帮忙完成,而操作系统实现线程之间的切换时需要从用户态转换原创 2021-04-21 16:50:10 · 512 阅读 · 1 评论 -
Java多线程中为什么调用 start() 方法时会执行 run() 方法,为什么不能直接调用 run() 方法?
为什么我们调用 start() 方法时会执行 run() 方法,为什么我们不能直接调用 run() 方法?new 一个 Thread,线程进入了新建状态;调用 start() 方法,会启动一个线程并使线程进入了就绪状态,当分配到时间片后就可以开始运行了。 start() 会执行线程的相应准备工作,然后自动执行 run() 方法的内容,这是真正的多线程工作。 而直接执行 run() 方法,会把 run 方法当成一个 main 线程下的普通方法去执行,并不会在某个线程中执行它,所以这并不是多线程工作。总结:原创 2021-04-21 16:08:59 · 1173 阅读 · 0 评论 -
sleep() 方法和 wait() 方法区别和共同点
sleep() 方法和 wait() 方法区别和共同点两者最主要的区别在于:sleep 方法没有释放锁,而 wait 方法释放了锁 。两者都可以暂停线程的执行。Wait 通常被用于线程间交互/通信,sleep 通常被用于暂停执行。wait() 方法被调用后,线程不会自动苏醒,需要别的线程调用同一个对象上的 notify() 或者 notifyAll() 方法。sleep() 方法执行完成后,线程会自动苏醒。或者可以使用 wait(long timeout)超时后线程会自动苏醒。...原创 2021-04-21 16:06:21 · 471 阅读 · 0 评论 -
为什么要使用多线程
为什么要使用多线程先从总体上来说:从计算机底层来说线程可以比作是轻量级的进程,是程序执行的最小单位,线程间的切换和调度的成本远远小于进程。另外,多核 CPU 时代意味着多个线程可以同时运行,这减少了线程上下文切换的开销。从当代互联网发展趋势来说现在的系统动不动就要求百万级甚至千万级的并发量,而多线程并发编程正是开发高并发系统的基础,利用好多线程机制可以大大提高系统整体的并发能力以及性能。再深入到计算机底层来探讨:单核时代在单核时代多线程主要是为了提高 CPU 和 IO 设备的综合利用率。举个原创 2021-04-20 23:11:53 · 1529 阅读 · 0 评论 -
什么是内存泄漏?有什么危害?
1、什么是内存泄漏内存泄漏是指你向系统申请分配内存进行使用(new/malloc),然后系统在堆内存中给这个对象申请一块内存空间,但当我们使用完了却没有归系统(delete),导致这个不使用的对象一直占据内存单元,造成系统将不能再把它分配给需要的程序。一次内存泄漏的危害可以忽略不计,但是内存泄漏堆积则后果很严重,无论多少内存,迟早会被占完,造成内存泄漏。2.Java内存泄漏引起的原因1、静态集合类引起内存泄漏:像HashMap、Vector等的使用最容易出现内存泄露,这些静态变量的生命周期和应用程原创 2021-04-20 23:11:13 · 5656 阅读 · 2 评论 -
什么是线程死锁?如何避免死锁?
认识线程死锁线程死锁描述的是这样一种情况:多个线程同时被阻塞,它们中的一个或者全部都在等待某个资源被释放。由于线程被无限期地阻塞,因此程序不可能正常终止。如下图所示,线程 A 持有资源 2,线程 B 持有资源 1,他们同时都想申请对方的资源,所以这两个线程就会互相等待而进入死锁状态。public class DeadLockDemo {private static Object resource1 = new Object();//资源 1private static Object resour原创 2021-04-20 22:53:27 · 334 阅读 · 0 评论 -
多线程编程中的上下文切换
什么是上下文切换多线程编程中一般线程的个数都大于 CPU 核心的个数,而一个 CPU 核心在任意时刻只能被一个线程使用,为了让这些线程都能得到有效执行,CPU 采取的策略是为每个线程分配时间片并轮转的形式。当一个线程的时间片用完的时候就会重新处于就绪状态让给其他线程使用,这个过程就属于一次上下文切换。上下文切换 (context switch) , 其实际含义是任务切换, 或者CPU寄存器切换。当多任务内核决定运行另外的任务时, 它保存正在运行任务的当前状态, 也就是CPU寄存器中的全部内容。这些内容原创 2021-04-20 22:38:35 · 1257 阅读 · 0 评论 -
并发与并行的区别
并发: 同一时间段,多个任务都在执行 (单位时间内不一定同时执行)(可以理解极快速间隔执行);并行: 单位时间内,多个任务同时执行。原创 2021-04-20 22:17:05 · 103 阅读 · 0 评论 -
从 JVM 角度了解进程和线程之间的关系
从上图可以看出:一个进程中可以有多个线程,多个线程共享进程的堆和方法区 (JDK1.8 之后的元空间)资源,但是每个线程有自己的程序计数器、虚拟机栈和本地方法栈。总结: 线程 是 进程 划分成的更小的运行单位。线程和进程最大的不同在于基本上各进程是独立的,而各线程则不一定,因为同一进程中的线程极有可能会相互影响。线程执行开销小,但不利于资源的管理和保护;而进程正相反。程序计数器为什么是私有的?程序计数器主要有下面两个作用:1.字节码解释器通过改变程序计数器来依次读取指令,从而实现代码的流程控制,如.原创 2021-04-20 22:14:17 · 355 阅读 · 0 评论 -
线程、程序、进程的基本概念,以及他们之间关系
线程、程序、进程的基本概念,以及他们之间关系线程与进程相似,但线程是一个比进程更小的执行单位。一个进程在其执行的过程中可以产生多个线程。与进程不同的是同类的多个线程共享同一块内存空间和一组系统资源,所以系统在产生一个线程,或是在各个线程之间作切换工作时,负担要比进程小得多,也正因为如此,线程也被称为轻量级进程。程序是含有指令和数据的文件,被存储在磁盘或其他的数据存储设备中,也就是说程序是静态的代码。进程是程序的一次执行过程,是系统运行程序的基本单位,因此进程是动态的。系统运行一个程序即是一个进程从创建原创 2021-04-19 22:01:48 · 565 阅读 · 0 评论 -
线程、进程
线程(thread)是操作系统能够进行运算调度的最小单位,它被包含在进程之中,是进程中的实际运作单位。假设你经营着一家物业管理公司。最初,业务量很小,事事都需要你亲力亲为。给老张家修完暖气管道,立马再去老李家换电灯泡——这叫单线程,所有的工作都得顺序执行。后来业务拓展了,你雇佣了几个工人,这样,你的物业公司就可以同时为多户人家提供服务了——这叫多线程,你是主线程。工人们使用的工具,是物业管理公司提供的,这些工具由大家共享,并不专属于某一个人——这叫多线程资源共享。工人们在工作中都需要管钳,可是管钳只有一原创 2021-03-31 15:49:54 · 117 阅读 · 1 评论 -
死锁 整理
什么是死锁:指的是多个线程在运行过程中为了争夺资源而出现的僵局,如果没有外力作用,那么这些线程都无法完成。例子:进程A现在拥有了资源1,并且想要请求资源2,但是资源2被进程B占有,并且此时进程B也在请求资源1,形成了他们同时都想申请对⽅的资源,所以这两个线程就会互相等待⽽进⼊死锁状态。死锁必备的四个条件:**互斥条件:**资源在某个时刻只能被一个进程所占用。(排他性控制)请求与保持条件:当前进程由于请求资源而阻塞时,对已拥有的资源保持不放。**不剥夺条件:**当前进程已经获得的资源在未使用完毕前不转载 2021-03-31 21:32:38 · 88 阅读 · 0 评论 -
模拟银行转账
1 JDBC+MySQLid number pk //用户idano varchar2(30) uk //用户卡号apassword varchar2(30) //用户密码aname varchar2(30) //用户名amoney number //余额 //创建银行用户表drop table bank_account;create table转载 2021-04-14 21:07:00 · 1948 阅读 · 0 评论 -
死锁---转账问题
死锁—转账问题/** 需求:简单的银行转账,它将资金从一个账户转到另一个账户* 在开始转账之前,需要获得两个Account的锁,以确保以原子的方式更新账户中的余额,且不能破坏不可变的条件,如账户的余额不能为负数* */ /*账户类*/class Account{ private String accountName;//账号 private int balance;//资金总额 public Account(String accountName,int balance转载 2021-04-14 22:14:15 · 270 阅读 · 0 评论 -
多线程案例--wait,notify,notifyAll,synchronized
等待唤醒机制线程间通信多个线程在处理同一个资源,但是处理的动作(线程的任务)却不相同。线程A用来生成包子的,线程B用来吃包子的,包子可以理解为同一资源,线程A与线程B处理的动作,一个 是生产,一个是消费,那么线程A与线程B之间就存在线程通信问题。等待唤醒机制方法:wait:线程不再活动,不再参与调度,进入 wait set 中,因此不会浪费 CPU 资源,也不会去竞争锁了,这时 的线程状态即是 WAITING。它还要等着别的线程执行一个特别的动作,也即是“通知(notify)”在这个对象 上转载 2021-04-14 23:01:50 · 153 阅读 · 0 评论 -
JAVA多线程的三种常用实现方式--Thread类,Runnable接口,匿名内部类
JAVA多线程的三种常用实现方式–Thread类,Runnable接口,匿名内部类Thread执行重写run()方法,new出线程对象.start()public class DemoThread extends Thread{ @Override public void run() { for (int i = 0; i <10 ; i++) { System.out.println("zilei"+i); } }原创 2021-04-15 16:29:02 · 379 阅读 · 0 评论 -
JAVA多线程的五种实现方式--Thread类,Runnable接口,匿名内部类,Callable和FutureTask,线程池
JAVA多线程的五种实现方式–Thread类,Runnable接口,匿名内部类,Callable和FutureTask,线程池Thread执行重写run()方法,new出线程对象.start()public class DemoThread extends Thread{ @Override public void run() { for (int i = 0; i <10 ; i++) { System.out.println("zile原创 2021-04-15 16:40:01 · 1197 阅读 · 1 评论 -
JAVA多线程安全之wait(),notify(),sleep(),synchronized(),lock(),BLOCKED状态
JAVA多线程安全之wait(),notify(),sleep(),synchronized(),lock(),BLOCKED状态sleep()sleep()中指定的时间是线程不会运行的最短时间。因此,sleep()方法不能保证该线程睡眠到期后就 开始立刻执行。BLOCKED(锁阻塞)Waiting(无限等待)某个对象的 Object.wait 方法的线程会等待另一个线程调用此对象的 Object.notify()方法 或 Object.notifyAll()方法。简单来讲,并发读写操原创 2021-04-15 17:01:48 · 291 阅读 · 0 评论 -
Hashtable和ConcurrentHashMap区别
Hashtable请看散列表(Hash table,也叫哈希表),是根据Key value而直接进行访问的数据结构。它通过把关键码值映射到表中一个位置来访问记录(类似索引),以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表。ConcurrentHashMapConcurrentHashMap是Java5中支持高并发、高吞吐量的线程安全HashMap实现,ConcurrentHashMap在jdk8的是Node[]数组。它由Segment数组结构和HashEntry数组结构组成。Se转载 2021-04-16 19:08:10 · 399 阅读 · 0 评论 -
HashTable详解(图文有代码)
HashTable详解散列表(Hash table,也叫哈希表),是根据Key value而直接进行访问的数据结构。它通过把关键码值映射到表中一个位置来访问记录(类似索引),以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表哈希表结构示例1、数组+链表2、数组+二叉树(链表树化)google公司的一个上机题:有一个公司,当有新的员工来报道时,要求将该员工的信息加入(id,性别,年龄,名字,住址…),当输入该员工的id时,要求查找到该员工的所有信息.要求:不使用数据库,速原创 2021-04-16 17:48:35 · 26354 阅读 · 5 评论