科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道Java线程安全同步解决方案

Java线程安全同步解决方案

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

 如果一个资源或对象可能被多个线程同时访问,它就是一个共享资源;例如类的成员变量,包括类变量和实例变量,再比如对一个文件进行写操作等。如果一个对象的完整生命周期只在一个线程内,则不需要考虑线程安全,例如一个局部变量。

作者:褚光华 来源:IT专家网 2008年4月17日

关键字: 同步 安全 线程 java

  • 评论
  • 分享微博
  • 分享邮件

2.1 如何同步保证线程安全

1、 问题描述:

  如果一个资源或对象可能被多个线程同时访问,它就是一个共享资源;例如类的成员变量,包括类变量和实例变量,再比如对一个文件进行写操作等。一般情况下,对共享资源的访问需要考虑线程安全的问题。

  如果一个对象的完整生命周期只在一个线程内,则不需要考虑线程安全,例如一个局部变量。下面为一个示例代码:

  1. public class C1 {
  2. public static java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy-MM-dd");
  3. //其他代码
  4. }

  假如在一个JSP中这样的去调用:

  1. <a.jsp>:
  2. <%
  3. Java.util.Date date = C1.sdf.parse(“2003-4-15”);
  4. %>

  则这样的代码不是线程安全的。因为java.text.SimpleDateFormat不是线程安全的,a.jsp中的代码将会有若干个线程同时执行,而都访问的是同一个线程不安全的对象,这样就不是一个线程安全的代码。正确的写法应该如下:

  1. <a.jsp>:
  2. <%
  3. java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy-MM-dd");
  4. Java.util.Date date = sdf.parse(“2003-4-15”);
  5. %>

2、 原因分析:

  此时,sdf对象从创建到销毁都位于一个方法中,相当于一个局部变量,不是一个共享资源,因此则没有线程不安全的问题。

3、 解决方法或过程:

1) 如果对象是immutable,则是线程安全的,例如:String,可以放心使用。
2) 如果对象是线程安全的,则放心使用
3) 有条件线程安全,对于Vector和Hashtable一般情况下是线程安全的,但是对于某些特殊情况,需要通过额外的synchronized保证线程安全。
4) 使用synchronized关键字;

  对于上例中可以改写jsp代码,在sdf上进行同步,而不需要每次创建一个新的对象来保证线程安全,代码如下:

  1. <%
  2. synchronized(C1.sdf){
  3. Java.util.Date date = C1.sdf.parse(“2003-4-15”);
  4. }
  5. %>

  这种写法是在一个对象级别上进行同步,也就是说任何时候,对于这个对象,最多只能有一个线程在执行同步方法。

  另外一种写法是在Class级别上进行同步,写法如下:

  1. public class C1 {
  2. public static java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy-MM-dd");
  3. public void method(){
  4. synchronized(C1.class){
  5. //synchronized code
  6. }
  7. }
  8. }

  这种写法表示无论C1有多少个实例,在任何一个时间点,最多只能有一个线程和一个实例进入同步块中。这种同步会比较大的影响性能。

  5) 有些对象不能在多线程间共享,则只能在方法内部使用,或者只在一个线程内部使用

    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章