![](https://img-blog.csdnimg.cn/20201014180756927.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
java多线程
文章平均质量分 65
你回到了你的家
这个作者很懒,什么都没留下…
展开
-
Java多线程-while死循环
示例代码如下所示:线程A执行methodA(),methodA()中有一个死循环线程B执行methodB(),当线程A进入methodA()中的死循环的时候,我们希望知道线程B能不能执行完成。import java.util.*;import java.util.concurrent.ThreadPoolExecutor;public class test { public static void main(String[] args) { Service servic原创 2020-10-10 20:09:17 · 3024 阅读 · 0 评论 -
Java线程间通信方式
一、通过synchronized关键字public class test { public static void main(String[] args) { MyObject object=new MyObject(); ThreadA threadA=new ThreadA(object); ThreadB threadB=new ThreadB(object); threadA.start(); threadB原创 2020-10-10 18:09:28 · 159 阅读 · 0 评论 -
多线程编程练习
一、多线程交替打印ABC建立三个线程A、B、C,A线程打印10次字母A,B线程打印10次字母B,C线程打印10次字母C,但是要求三个线程同时运行,并且实现交替打印,即按照ABCABCABC的顺序打印。1.1 synchronized同步public class test { public static class ThreadPrinter implements Runnable{ private String name; private Object pre原创 2020-09-23 13:56:49 · 212 阅读 · 0 评论 -
守护线程
一、什么是守护线程在Java中有两类线程:User Thread(用户线程)、Daemon Thread(守护线程)用个比较通俗的比如,任何一个守护线程都是整个JVM中所有非守护线程的保姆:只要当前JVM实例中尚存在任何一个非守护线程没有结束,守护线程就全部工作;只有当最后一个非守护线程结束时,守护线程随着JVM一同结束工作。Daemon的作用是为其他线程的运行提供便利服务,守护线程最典型的应用就是 GC (垃圾回收器),它就是一个很称职的守护者。User和Daemon两者几乎没有区别,唯一的不同之原创 2020-09-23 09:24:20 · 84 阅读 · 0 评论 -
生产者消费者问题
一、使用wait、notify实现import java.util.*;public class test { public static void main(String[] args) { AbstractStorage abstractStorage=new Storage(); Producer p1=new Producer(abstractStorage); Producer p2=new Producer(abstractStor原创 2020-09-23 08:47:55 · 86 阅读 · 0 评论 -
synchronized与reentrantlock的区别
一、相似点这两种同步方式有很多相似之处,它们都是加锁方式同步,而且都是阻塞式的同步,也就是说当如果一个线程获得了对象锁,进入了同步块,其他访问该同步块的线程都必须阻塞在同步块外面等待,而进行线程阻塞和唤醒的代价是比较高的(操作系统需要在用户态与内核态之间来回切换,代价很高,不过可以通过对锁优化进行改善)。二、功能区别这两种方式最大区别就是对于Synchronized来说,它是java语言的关键字,是原生语法层面的互斥,需要jvm实现。而ReentrantLock它是JDK 1.5之后提供的API层面的原创 2020-09-14 10:00:40 · 123 阅读 · 0 评论 -
synchronized偏向锁、轻量级锁、重量级锁
为了换取性能,JVM在内置锁上做了非常多的优化,膨胀式的锁分配策略就是其一。理解偏向锁、轻量级锁、重量级锁的要解决的基本问题,几种锁的分配和膨胀过程,有助于编写并优化基于锁的并发程序。一、隐藏在内置锁下的基本问题内置锁是JVM提供的最便捷的线程同步工具,在代码块或方法声明上添加synchronized关键字即可使用内置锁。使用内置锁能够简化并发模型;随着JVM的升级,几乎不需要修改代码,就可以直接享受JVM在内置锁上的优化成果。从简单的重量级锁,到逐渐膨胀的锁分配策略,使用了多种优化手段解决隐藏在内置锁原创 2020-09-14 09:40:29 · 211 阅读 · 0 评论 -
Java多线程如何确定线程数
一、Java并发编程实战仔细观察上面两个公式,其实是类似的,在CPU使用率达到100%时,其实结论是一致的,这时候计算线程的公式就变成了:Nthreads=Ncpu∗100%∗(1+w/c)N_{threads}=N_{cpu}*100\%*(1+w/c)Nthreads=Ncpu∗100%∗(1+w/c)根据上面的公式,我们在实践应用中计算的公式就出来了,如下:针对IO密集型的:阻塞耗时w一般都是计算耗时的几倍,假设阻塞耗时=计算耗时的情况下,Nthreads=Ncpu∗(1+1)=2Nc原创 2020-09-04 11:29:24 · 409 阅读 · 0 评论 -
Java CAS
一、CAS是什么?CAS是compare and swap的简称,从字面上理解就是比较并更新,简单来说:从某一个内存上取V,和预期值A进行比较,如果内存V和预期值A的结果相等,那么我们就把新值B更新到内存,如果不相等,那么就重复上述操作直到成功为止。这是一种实现并发算法时常用到的技术。二、CAS能做什么?CAS可以解决多线程并发安全的问题,以前我们对一些多线程操作的代码都是使用synchronized关键字,来保证线程安全的问题;现在我们将CAS放入到多线程环境里我们看一下它是怎么解决的:我们假设有原创 2020-09-03 15:25:11 · 152 阅读 · 0 评论 -
Java对象头与monitor
由于Java面向对象的思想,在JVM中需要大量存储对象,存储时为了实现一些额外的功能,需要在对象中添加一些标记字段用于增强对象功能,这些标记字段组成了对象头。一、对象头形式JVM中对象头的方式有以下两种(以32位JVM为例)1.1 普通对象1.2 数组对象二、对象头的组成2.1 Mark Word这部分主要用来存储对象自身的运行时数据,如hashcode、gc分代年龄等。mark word的位长度为JVM的一个Word大小,也就是说32位JVM的Mark word为32位,64位JVM为6原创 2020-09-03 15:11:35 · 4662 阅读 · 2 评论 -
Java进程通信
一、共享内存特点:可被多个进程打开访问读写操作的进程在执行读写操作时,其他进程不能进行写操作多个进程可以交替对某一共享内存执行写操作一个进程执行内存写操作后,不影响其他进程对该内存的访问,同时其他进程对更新后的内存具有可见性Java进程间的共享内存通过内存映射文件(MappedByteBuffer)实现,不同进程的内存映射文件关联到同一物理文件。该文件通常为随机存取文件对象,实现文件和内存的映射,即时双向同步。...原创 2020-09-01 12:31:36 · 1115 阅读 · 0 评论 -
Java NIO
一、NIO基础知识NIO(Non-blocking I/O,在Java领域,也称为New I/O),是一种同步非阻塞的I/O模型,也是I/O多路复用的基础,已经被越来越多地应用到大型应用服务器,成为解决高并发与大量连接、I/O处理问题的有效方式。1.1 概述NIO主要有三大核心部分:Channel(通道),Buffer(缓冲区), Selector。传统IO基于字节流和字符流进行操作,而NIO基于Channel和Buffer(缓冲区)进行操作,数据总是从通道读取到缓冲区中,或者从缓冲区写入到通道中。S原创 2020-09-01 09:07:40 · 150 阅读 · 0 评论 -
NIO相关基础
一、用户空间以及内核空间概念我们知道现在操作系统都是采用虚拟存储器,那么对32位操作系统而言,它的寻址空间(虚拟存储空间)为4G(2的32次方)。操作系统的核心是内核,独立于普通的应用程序,可以访问受保护的内存空间,也有访问底层硬件设备的所有权限。为了保证用户进程不能直接操作内核,保证内核的安全,操作系统将虚拟空间划分为两部分,一部分为内核空间,一部分为用户空间。针对linux操作系统而言,将最高的1G字节(从虚拟地址0xC0000000到0xFFFFFFFF),供内核使用,称为内核空间,而将较低的3G字原创 2020-09-01 08:14:45 · 155 阅读 · 0 评论 -
Java进程间通信
一、进程通信的目的1.1 数据共享一个进程需要将它的数据发送给另一个进程1.2 资源共享多个进程之间共享同样的资源1.3 通知事件一个进程需要向另一个或一组进程发送消息,通知它(它们)发生了某种事件1.4 进程控制有些进程希望完全控制另一个进程的执行(例如Debug进程),此时控制进程希望能够拦截另一个进程的所有陷入和异常,并能够及时知道它的状态改变。二、进程通信的方式...原创 2020-09-01 07:40:01 · 180 阅读 · 0 评论 -
synchronized关键字
一、synchronized锁synchronized用的锁是存在Java对象里头的。JVM基于进入和退出Monitor对象来实现方法同步和代码块同步。代码块同步是使用monitorenter和moniterexit指令实现的,monitorenter指令是在编译后插入到同步代码块的开始位置,而monitorexit是插入到方法结束处和异常处。任何对象都有一个monitor与之关联,当且仅当一个monitor被持有后,它将处于锁定状态。根据虚拟机规范的要求,在执行monitorenter指令时,首先要原创 2020-08-31 22:07:33 · 216 阅读 · 0 评论 -
通过Callable和FutureTask创建线程
一、使用步骤虽然Runnable接口实现多线程比继承Thread类实现多线程方法要好,但是Runnable接口里的run方法并不能返回操作结果。为了解决这样的矛盾,java提供了Callable接口。创建并启动有返回值的线程的步骤如下:创建Callable接口的实现类,并实现call()方法,该call()方法将作为线程执行体,且该call()方法有返回值,再创建Callable实现类的实例使用FutureTask类来包装Callable对象,该FutureTask对象封装了该Callable对象原创 2020-08-30 09:22:05 · 2262 阅读 · 0 评论 -
Java多线程实现-Runnable接口
一、步骤定义Runnable接口的实现类,并重写该接口的run()方法,该run()方法的方法体同样是该线程的线程执行体创建Runnable实现类的实例,并以此实例作为Thread的target来创建Thread对象,该Thread对象才是真正的线程对象调用线程对象的start()方法来启动该线程二、Runnable接口源码这是一个函数式接口,规定里面只有一个run方法,如果一个类要实现这个接口,需要重写其中的run方法。当一个实现了Runnable接口的实例被用来创建一个新的线程,这个新的线原创 2020-08-29 18:24:28 · 3304 阅读 · 0 评论 -
Java线程状态
一、线程状态定义Thread类中的定义如下:/** * A thread state. A thread can be in one of the following states: * <ul> * <li>{@link #NEW}<br> * A thread that has not yet started is in this state. * </li> * <l原创 2020-08-28 21:59:31 · 165 阅读 · 0 评论 -
volatile关键字
一、相关知识1.1 内存可见性线程对共享变量修改的可见性。当一个线程修改了共享变量的值,其他线程能够立刻得知这个修改。volatile使用Lock前缀的指令禁止线程本地内存缓存,保证不同线程之间的内存可见性。Java代码如下://instance是volatile变量Singleton volatile instance = new Singleton(); 转变成汇编代码如下:0x01a3de1d: movb $0×0,0×1104800(%esi);0x01a3de24: lock原创 2020-08-28 17:22:23 · 434 阅读 · 0 评论 -
Java内存模型(JMM)
一、Java内存模型介绍Java虚拟机规范中定义了Java内存模型(Java Memory Model,JMM),用于屏蔽掉各种硬件和操作系统的内存访问差异,以实现让Java程序在各种平台下都能达到一致的并发效果,JMM规范了Java虚拟机与计算机内存是如何协同工作的:规定了一个线程如何和何时可以看到由其他线程修改过后的共享变量的值,以及在必须时如何同步的访问共享变量。Java内存模型(不仅仅是JVM内存分区):调用栈和本地变量存放在线程栈上,对象存放在堆上。本地变量的存储位置:一个本地变量可原创 2020-08-28 14:34:26 · 247 阅读 · 0 评论 -
Java多线程实现-线程池
在《阿里巴巴Java手册》里有这样一条:【强制】线程资源必须通过线程池提供,不允许在应用中自行显式创建线程。说明:使用线程池的好处是减少在创建和销毁线程上所花的时间以及系统资源的开销,解决资源不足的问题。如果不使用线程池,有可能造成系统创建大量同类线程而导致消耗完内存或者“过度切换”的问题。简单来说使用线程池有以下几个目的:线程是稀缺资源,不能频繁的创建解耦作用:线程创建时执行完全分开,方便维护可以将其放入一个池子中,方便给其他任务进行复用一、线程池原理谈到线程池就会想到池化技术,其中最原创 2020-08-28 07:08:50 · 1454 阅读 · 1 评论 -
Main线程与main()方法的关系
当JVM启动的时候,会启动一个名为“Main”的线程。程序就会在这个线程上运行,除非用户自己创建了其他线程。Main线程首先就会寻找"static void main(String[] args)"方法,并且调用这个方法。这个就是程序的进入点。如果我们希望程序可以并发,那么我们可以创建多线程,并且给予每个线程一些操作。接下来这些线程就会并发的执行这些操作。JVM同时也会创建一些其他的内部线程在“幕后”工作(比如垃圾回收)。...原创 2020-08-24 15:32:21 · 668 阅读 · 0 评论 -
Java多线程实现-Thread类
一、实现过程Thread类是一个支持多线程的功能类,只要有一个子类它就可以实现多线程。所有程序的起点是main方法,所有线程也有一个自己的起点,run方法,多线程的每个主体类之中都必须覆盖Thread类中所提供的run方法,Thread类中run的源码如下:/** * If this thread was constructed using a separate * <code>Runnable</code> run object, then that原创 2020-08-24 15:13:19 · 306 阅读 · 0 评论 -
多线程实现方式
一、介绍多线程共有四种实现方式:继承Thread类,重写run方法实现Runnable接口,重写run方法,实现Runnable接口的实现类的实例对象作为Thread构造函数的target通过Callable和FutureTask创建线程通过线程池创建线程前面两种可以归结为一类:无返回值,原因很简单,通过重写run方法,run方式的返回值是void,所以没有办法返回结果。后面两种可以归结成一类:有返回值,通过Callalbe接口,就要实现call方法,这个方法的返回值是Object,所以返原创 2020-08-24 07:56:59 · 209 阅读 · 0 评论 -
多线程常用方法
一、命名与获取多线程每一次运行都是不同的运行结果,因为它会根据自己的情况进行资源抢占(除非加锁)。要区分每一个进程,那么必须依靠线程的名字。对于线程名字,一般而言会在其启动之前进行定义,不建议对已经启动的线程更改名称/设置不同线程重名。如果要进行线程名称的操作,可以使用Threa类如下方法:构造方法:/** * Allocates a new {@code Thread} object. This constructor has the same * effect as {@li原创 2020-08-23 23:03:35 · 344 阅读 · 0 评论