`
dbp_cn
  • 浏览: 86296 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论
文章列表

重入线程

 当某个线程请求一个由其他线程持有的锁时,发出的请求的线程就会阻塞。然而,由于内置锁是可重入的,因此如果某个线程试图获得一个已经由它自己持有的锁,那么这个请求就会成功。”重入“ 意味着获取锁的操作的粒度是“线程”,而不是“调用”。重入的一种实现方法是 为每个锁关联一个获取计数值和一个所有者线程。当计数值为0时,JVM将记下锁的持有者,并且将获取计数值置为1。如果同一个线程再次获取这个锁,计数值将递增,而当线程退出同步代码块时,计数器会响应地递减。当计数值为0时,这个锁将被释放。 public class Widget{ public synchronized void doSom ...

内置锁

Java 提供了一种内置锁机制来支持原子性:同步代码块。同步代码块包括两部分:一个作为锁的对象引用,一个作为由这个锁保护的代码块。以关键字synchronized来修饰的方法就是一种横跨整个方法体的同步代码块,其中 该同步代码块的锁就是方法调用所在的对象。静态的synchronized方法以Class对象作为锁。   synchronized(lock){ //访问或修改由锁保护的共享状态 }  每个Java对象都可以用做一个实现同步的锁,这些锁被称为内置锁(Intrisic Lock)或监视器锁(Monitor Lock)。线程在进入同步代码块之前会自动获得锁,并且在退出同步代码块 ...

复合操作

我们将“先检查后执行”以及“读取-修改-写入"等操作统称为符合操作:包含了一组必须以原子方式执行的操作以确保线程安全性。后面我们会讨论加锁机制,这是Java中用于确保原子性的内存机制,我们还可以使用一个现有的线程安全类: public class CountingFactorizer implements Servlet{ private final AtomicLong count=new AtomicLong(0); public long getCount(){return count.get();} public void se ...
 使用“先检查后执行”的一种常见情况就是延迟初始化。延迟初始化的目的是将对象的初始化推迟到实际使用时才进行,同时要确保只被初始化一次。    public class LazyInitRace{ private ExpensiveObject instance=null; public ExpensiveObject getInstance(){ if(instance==null) instance=new ExpensiveObject(); return instance; } } ...

原子性

当我们在无状态的对象中增加一个状态时,会出现什么情况?假设我们希望增加一个“命中计数器”来统计所处理的请求数量。一种直观的方法是 在Servlet中增加一个long 类型的域,并且每处理一个请求就 将这个值加1,如下程 ...
示例:      通常,线程安全性的需求并非来源于对线程的直接使用,而是使用相Servlet这样的框架。我们来看一个简单的例子:一个基于Servlet的因数分解服务,并逐渐扩展它的功能,同时确保它的线程安全性。     这个Servlet从请求中提取出数值,执行因数分解,然后将结果封装到该Servlet的响应中   public class StatelessFactorizer implements Servlet{ public void service(ServletRequest req,ServletResponse resp){ BigInteg ...
有些导入eclipse的项目中,没有被eclipse检测成java项目,项目目录的左上角没有J字母,应该是.project没有配置好,需要给此项目配置一个插件,如下: <?xml version="1.0" encoding="UTF-8"?> <projectDescription> <name>ProjectDemo</name> <comment>NO_M2ECLIPSE_SUPPORT: Project files created with the maven-eclip ...
“共享”意味着变量可以由多个线程同时访问,而“可变”则意味着变量的值在其生命周期内可以发生变化。一个对象是否需要是线程安全的,取决于它是否被多个线程访问。要使得对象是线程安全的,需要采用同步机制来协同对对象可变状态的访问。 当多个线程访问某个状态变量并且其中有一个线程执行写入操作时,必须采用同步机制来协同这些线程对变量的访问。Java中的主要同步机制是关键字synchronized,它提供了一种独占的加锁方式,但“同步”这个术语还包括volatile类型的变量,主要用于显式锁以及原子变量。  如果当多个线程访问同一个可变的状态变量时没有使用合适的同步,程序就会出错,有三种方式可以修复这个 ...
UseSerialGC  :虚拟机运行在Client模式下的默认值,打开此开关后,使用Serial+Serial Old组合进行内存回收。 UseParNewGC :打开此开关后,使用ParNew+Serial Old组合回收 UseConcMarkSweepGC:打开此开关后,使用ParNew+CMS+Serial Old 的收集器组合进行内存回收,Serial Old 收集器将作为CMS收集器出现Concurrent Mode Failure失败后的后备收集器使用 UseParallerGC:虚拟机运行在Server模式下的默认值,打开此开关后,使用Parallel Scavenge ...
Java技术体系中所提倡的自动内存管理最终可以归结为 自动化地解决了两个问题 : 给对象分配内存以及回收分配个对象的内存。接下来我们来讲一讲内存分配的事情。   对象的内存分配,往大方向讲,就是在堆上分配,对象主要分配在新生代的Eden上,如果启动了本地线程分配缓冲,将按线程优先在TLAB上分配。少数情况下也可能会直接分配在老年代中。 1,对象优先在Eden分配    大多数情况下,对象在新生代Eden区中分配。当Eden区没有足够的空间进行分配时,虚拟机将发起一次Minor GC。   虚拟机提供了-XX:PrintGCDetails这个收集器日志参数,告诉虚拟机在发生垃圾收集行为 ...

垃圾收集器

1. Serial 收集器       ("Serial" is a stop-the-world, copying collector which uses a single GC thread.)   Serial收集器是最基本,历史最悠久的收集器,使用复制算法,在jdk 1.3.1之前是 虚拟机新生代收集的唯一选择,它是单线程的收集器,它在进行垃圾收集时,必须暂停其他所有的工作线程(Sun将其称为"stop the world"),直到它收集结束。"stop the world"这项工作实际上是由虚拟机在后台自动发起和 ...
1,标记-清除算法     最基础的收集算法是“标记-清除”算法,如它的名字一样,算法分为“标记”和“清除”两个阶段:首先标记出所有需要回收的对象,在标记完成后统一回收掉所有的对象。之所以所它是最基础的收集算 ...

再谈引用

有些对象,当内存空间还足够时,则希望能保留在内存中;如果内存在进行垃圾收集后还是非常紧张,则可以抛弃这些对象。很多系统缓存功能都符合这样的应用场景。  在JDK1.2之后,Java对引用的概念进行了扩充,将引用分为强引用,软引用,弱引用,虚引用四种,这四种引用强度依次逐渐减弱。   强引用就是指在程序代码之中普遍存在的,类似:Object obj=new Object() 这类的引用,只要强引用还存在,垃圾收集器永远不会回收掉被引用的对象。        软引用用来描述一些还有用但并非必需的对象。对于软引用关联着的对象,在系统将要发生内存溢出异常之前,将会把这些对象列进回收范围之中并进行 ...
堆中几乎存放这Java世界中所有的对象实例,垃圾收集器在对堆进行回收前,第一件事情就是要确定这些对象有哪些还"存活"着,哪些已经"死去"(即不可能再被任何途径使用的对象)。 1,引用计数算法   给对象添加一个引用计数器,每当有一个地方引用它时,计数器就加1;当引用失效时,计数器就减1;任何时刻计数器都为0的对象就是不可能再被使用的。客观地讲,引用计数法的实现简单,判定效率也高,但Java中没有选用其来管理内存,其中最主要的原因是它很难解决对象之间的相互循环引用的问题。  例子:    如下代码,对象objA和objB都有字段instance,赋 ...
java虚拟机运行时区域图: 1,程序计数器: 程序计数器可以看作是当前线程所执行的字节码的行号指示器。字节码解释器工作时就是通过改变这个计数器的值来选取下一条需要执行的字节码指令,分支,循环,跳转,异常 ...
Global site tag (gtag.js) - Google Analytics