java 无状态和有状态区别
诸位Java程序员,想必大家对SimpleDateFormat并不陌生。不过,你是否知道,SimpleDateFormat不是线程安全的(thread safe)。这意味着,下面的代码是错误的:
class Sample {
private static final DateFormat format = new SimpleDateFormat("yyyy.MM.dd");
public String getCurrentDateText() {
return format.format(new Date());
}
}
从功能的角度上看,单独执行这段代码是没有问题的,但放到多线程环境下,因为SimpleDateFormat不是线程安全的,这段代码就会出错。所以,要想让这段代码正确,我们只要稍做微调:
public class Sample {
public String getCurrentDateText() {
return new SimpleDateFormat("yyyy.MM.dd").format(new Date());
}
}
不知你是否注意到,这里的调整只是由原来的共享format这个变量,变成了每次调用这个方法时创建出一个新的SimpleDateFormat变量。
作为一个专业程序员,我们当然知道,相比于共享一个变量的开销要比每次创建小。之所以我们必须这么做,是因为SimpleDateFormat不是线程安全的。但从SimpleDateFormat提供给我们的接口上来看,实在让人看不出它与线程安全有和相干。那接下来,我们就要打开JDK的源码,看一下其中的代码之丑。
如果你手头没有JDK的源码,这里是个不错的参考。
在format方法里,有这样一段代码:
calendar.setTime(date);
其中,calendar是DateFormat的protected字段。这条语句改变了calendar,稍后,calendar还会用到(在subFormat方法里),而这就是引发问题的根源。
想象一下,在一个多线程环境下,有两个线程持有了同一个SimpleDateFormat的实例,分别调用format方法:
线程1调用format方法,改变了calendar这个字段。
中断来了。
线程2开始执行,它也改变了calendar。
又中断了。
线程1回来了,此时,calendar已然不是它所设的值,而是走上了线程2设计的道路。
BANG!!! 稍微花点时间分析一下format的实现,我们便不难发现,用到calendar,唯一的好处,就是在调用subFormat时,少了一个参数,却带来了这许多的问题。其实,只要在这里用一个局部变量,一路传递下去,所有问题都将迎刃而解。
这个问题背后隐藏着一个更为重要的问题:无状态。
无状态方法的好处之一,就是它在各种环境下,都可以安全的调用。衡量一个方法是否是有状态的,就看它是否改动了其它的东西,比如全局变量,比如实例的字段。format方法在运行过程中改动了SimpleDateFormat的calendar字段,所以,它是有状态的。
写程序,我们要尽量编写无状态方法。
------------------------------------------------------------------------------------------------------------------
有状态:
Java对象的状态用属性来表示,有属性,也就是对象的变量,就表示是有状态的,有状态就是线程不安全的。
关于线程安全:
1) 常量始终是线程安全的,因为只存在读操作。
2)每次调用方法前都新建一个实例是线程安全的,因为不会访问共享的资源。
3)局部变量是线程安全的。因为每执行一个方法,都会在独立的空间创建局部变量,它不是共享的资源。局部变量包括方法的参数变量和方法内变量。
java 无状态和有状态区别的更多相关文章
- OID,主键生成策略,PO VO DTO,get和load区别,脏检查,快照,java对象的三种状态
主键生成策略 sequence 数据库端 native 数据库端 uuid 程序端 自动赋值 生成的是一个32位的16进制数 实体类需把ID改成String 类型 assigned 程序端 需手 ...
- hibernate中的java对象有几种状态,其相互关系如何(区别和相互转换)。
hibernate中的java对象有几种状态,其相互关系如何(区别和相互转换). 解答:在Hibernate中,对象有三种状态:临时状态.持久状态和游离状态. 临时状态:当new一个实体对象后,这个对 ...
- 线程、进程的区别,Java的几个线程状态
线程.进程的区别 进程的定义:进程就是程序在一个数据集合上的一次执行过程.他与程序的区别在于程序是静态的代码,而进程是动态的执行过程. 进程的特性:1.结构性,进程由程序块.数据块.进程 ...
- java 线程的几种状态
java thread的运行周期中, 有几种状态, 在 java.lang.Thread.State 中有详细定义和说明: NEW 状态是指线程刚创建, 尚未启动 RUNNABLE 状态是线程正在正常 ...
- http协议无状态中的 "状态" 到底指的是什么?!
引子: 最近在好好了解http,发现对介绍http的第一句话[http协议是无状态的,无连接的]就无法理解了:无状态的[状态]到底指的是什么?! 找了很多资料不仅没有发现有一针见血正面回答这个问题的, ...
- Java线程状态Jstack线程状态BLOCKED/TIMED_WAITING/WAITING解释
一.线程5种状态 新建状态(New) 新创建了一个线程对象. 就绪状态(Runnable) 线程对象创建后,其他线程调用了该对象的start()方法.该状态的线程位于可运行线程池中,变得可运行,等待获 ...
- Java线程Thread的状态解析以及状态转换分析 多线程中篇(七)
线程与操作系统中线程(进程)的概念同根同源,尽管千差万别. 操作系统中有状态以及状态的切换,Java线程中照样也有. State 在Thread类中有内部类 枚举State,用于抽象描述Java线程的 ...
- 设计模式《JAVA与模式》之状态模式
在阎宏博士的<JAVA与模式>一书中开头是这样描述状态(State)模式的: 状态模式,又称状态对象模式(Pattern of Objects for States),状态模式是对象的行为 ...
- 【转】java 线程的几种状态
java thread的运行周期中, 有几种状态, 在 java.lang.Thread.State 中有详细定义和说明: NEW 状态是指线程刚创建, 尚未启动 RUNNABLE 状态是线程正在正常 ...
- Java线程基础知识(状态、共享与协作)
1.基础概念 CPU核心数和线程数的关系 核心数:线程数=1:1 ;使用了超线程技术后---> 1:2 CPU时间片轮转机制 又称RR调度,会导致上下文切换 什么是进程和线程 进程:程序运行资源 ...
随机推荐
- 求满足n^2>12000的n的最大值 Exercise05_13
/** * @author 冰樱梦 * 时间:2018年下半年 * 题目:求满足n^2>12000的n的最大值 * */ public class Exercise05_13 { public ...
- 长按事件OnLongClickListener
1.MainActivity.java package com.example.administrator.hello4; import android.support.v7.app.AppCompa ...
- YS端对端之间SSL通信安全问题
1.简介: 传统的互联网,SSL通信主要基于客户端和服务器之间,在物联网时代,端和端之间的加密通信将变得很普遍,在YS业务中主要的端和端通信为: (1).客户端(移动APP,YS工作 ...
- 直接拿来用!最火的iOS开源项目(三)
相比Android,GitHub上的iOS开源项目更可谓是姹紫嫣红.尽管效果各异,但究其根源,却都是因为开发者本身对于某种效果的需求以及热爱.在“直接拿来用!最火的iOS开源项目”系列文章(一).(二 ...
- 手把手教你调试Entity Framework 6源码
0 摘要 本文讲述在Visual Studio 2013(VS 2013)下调试Entity Framework 6(EF 6)源码的配置过程.原则上,VS 2012也适用. 之前打算编写<E ...
- android BSP与硬件相关子系统读书笔记(1)android BSP移植综述
从linux驱动转行至Android驱动开发大半年了,一开始就产生了一个很纠结目标和问题,就是不停的google如何porting android!这个问题得到的结果对于初出茅庐的我,感到迷惘.随着工 ...
- python 下载小说
以下载官场风月小说为例: 具体代码: # coding=utf-8 import os import re from selenium import webdriver from selenium.c ...
- Managed Media Aggregation using Rtsp and Rtp
his article was written almost 2 years ago, it's content may not reflect the latest state of the cod ...
- Amixer 控制声音
amixer set Master XXXX 就可以直接控制主声卡属性 amixer set Master 20 #设置主声卡声音为 20 amixer set Master off #关闭主声卡(静 ...
- LInux——安装Apache
在安装Apache的httpd的时候经常会遇到: configure: error: APR not found . Please read the documentation. configure ...