`
齐晓威_518
  • 浏览: 618992 次
  • 性别: Icon_minigender_1
  • 来自: 郑州
社区版块
存档分类
最新评论

synchronized 和ThreadLocal 区别

 
阅读更多

看了N个贴子,ThreadLocal讲得都不是很清楚,纠缠与synchronized的区别。直到看了http://qqdwll.iteye.com/blog/685586 才清晰了ThreadLocal的作用。

 

ThreadLocal可以为每个线程维护自己的变量,对于多线程使用同一对象可以起到管理作用。

package com.koubei.Observable;

import com.sun.org.apache.xalan.internal.xsltc.compiler.sym;

public class UserProcess implements Runnable{

    private UserDAO userDAO;
   
    public UserProcess(UserDAO userDAO){
        this.userDAO = userDAO;
    }
   
    public  void run() {
        // TODO Auto-generated method stub
        for(int i=0; i<1000; i++){
           
            userDAO.insertUser(getUser());
        }
    }

   
   
    public static void main(String[] args) {
        UserDAO userDAO = new UserDAO();
       
        new Thread(new UserProcess(userDAO)).start();
        new Thread(new UserProcess(userDAO)).start();
        new Thread(new UserProcess(userDAO)).start();
       
       
    }
}

Java代码

package com.koubei.Observable;

import java.sql.Connection;

public class UserDAO {

    private Connection conn = null;
   
    public UserDAO(){
       
    }
   
    public void insertUser(User user){
       
          getConn().prepareStatement(sql);
       
        //jdbc 操作
    }
   
    public synchronized Connection getConn(){
        if (conn == null) {
            try {
                Class.forName("com.mysql.jdbc.Driver");
                CONN = DriverManager.getConnection("jdbc:mysql://"
                        + DB_IP + ":" + "3306" + "/" + DB_NAME
                        + "?useUnicode=true&characterEncoding=gbk", DB_USER,
                        DB_PASSWORD);
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
        return conn;
    }
}

在UserProcess中多个线程引用的同一个UserDAO,在线程运行后所有的语句都是通过一个Connection执行。

 

问题:

1、多个线程使用同一个conn效率比较低,存在数据共享问题。影响效率

 

改进:

1、希望UserDAO中为每个线程开立一个conn,各线程使用自己的连接执行sql

 

改进后的代码

package com.koubei.Observable;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class UserDAO {

    private static ThreadLocal<Connection> connThreadLocal = new ThreadLocal<Connection>();
   
   
    public UserDAO(){
       
    }
   
    public void insertUser(User user){
       
        getConnection().prepareStatement(sql);
       
        //jdbc 操作
    }
    
    public Connection getConnection(){  
        if (connThreadLocal.get() == null) {

            Connection conn = getConn();

            connThreadLocal.set(conn);

            return conn;

        }
       
        return connThreadLocal.get();

    }

   
   
    public synchronized  Connection getConn(){
        try{
            Class.forName("com.mysql.jdbc.Driver");
            return DriverManager.getConnection("jdbc:mysql://"
                    + DB_IP + ":" + "3306" + "/" + DB_NAME
                    + "?useUnicode=true&characterEncoding=gbk", DB_USER,
                    DB_PASSWORD);
        }cache(SQLException e){
           e.printStackTrace();  
        }
        return null;
      
    }
}

改动后每个线程都会维护自己的conn,userDAO变成线程安全的。

 

 synchronized 是解决多个线程访问同一个变量

 ThreadLocal 是每个线程维护自己专用的变量

 两者使用场景不一样,作用也不一样。

分享到:
评论

相关推荐

    Synchronized与ThreadLocal

    #### 三、Synchronized与ThreadLocal的区别 - **同步机制:** - Synchronized 是通过加锁来实现同步,确保同一时刻只有一个线程能访问被同步的代码块或方法。 - ThreadLocal 并不提供同步机制,而是为每个线程...

    ThreadLocal

    ThreadLocal通常被用来解决线程共享数据时可能出现的并发问题,避免了使用synchronized关键字进行同步控制的复杂性。 在Java中,ThreadLocal的工作原理是为每个线程创建一个单独的存储空间,每个线程可以独立地读写...

    Java中ThreadLocal的设计与使用

    ### ThreadLocal与静态成员变量的区别 静态成员变量是所有线程共享的,而ThreadLocal变量为每个线程提供独立的副本。这使得ThreadLocal适合于存储线程私有数据,如数据库连接、用户会话信息等。 ### ThreadLocal的...

    ThreadLocal源码分析和使用

    ThreadLocal 源码分析和使用 ThreadLocal 是 Java 语言中的一种多线程编程机制,用于解决多线程程序的并发问题。它不是一个 Thread,而是一个 Thread 的局部变量。ThreadLocal 的出现是为了解决多线程程序中的共享...

    Java多线程 之 临界区、ThreadLocal.docx

    Java多线程编程中,临界区和ThreadLocal是两种重要的并发控制机制,它们用于解决多线程环境下的数据安全问题。 1. **临界区(Critical Section)** 临界区是指一段代码,它在同一时刻只允许一个线程进行访问。在...

    ThreadLocal详解

    与传统的使用`synchronized`关键字或`Lock`接口来实现线程同步不同,ThreadLocal提供了另一种解决线程安全问题的思路——即为每个线程创建独立的变量副本,避免了线程间的变量共享所带来的同步问题,从而提高了程序...

    8个案例详解教会你ThreadLocal.docx

    1. **与 Synchronized 的区别** - `synchronized` 关键字是用于控制对共享资源的并发访问,它确保同一时刻只有一个线程可以执行特定代码块,从而实现线程同步。而 `ThreadLocal` 不是同步机制,它提供的是线程局部...

    深入理解 Java 之 ThreadLocal 工作原理1

    这个设计模式在多线程编程中尤其有用,因为它避免了传统的同步机制,如synchronized和Lock,从而提高了并发性能。 首先,我们要明确ThreadLocal并不是一个线程局部变量,而是一个类,它提供了一个全局的引用,但是...

    2、导致JVM内存泄露的ThreadLocal详解

    在多线程编程中,为了避免线程间的数据竞争和保证线程安全性,常常需要使用同步机制如`synchronized`来控制线程对共享资源的访问。然而,这种方式可能会带来性能上的损失,尤其是在高并发场景下。此外,频繁地加锁...

    彻底理解ThreadLocal 1

    ThreadLocal是Java中用于线程局部变量的一个工具类,它允许在多线程环境下为每个线程创建独立的变量副本,从而避免了线程之间的数据共享和由此引发的并发问题。ThreadLocal不是一种线程同步机制,而是提供了一种线程...

    java核心知识点学习----多线程间的数据共享和对象独立,ThreadLocal详解.pdf

    为了解决这个问题,我们可以使用线程局部变量(ThreadLocal)或者通过同步机制如synchronized关键字来实现线程间的数据隔离。 1. **线程内的数据共享与对象独立**: 在例子中,使用了HashMap来存储每个线程的数据...

    18 线程作用域内共享变量—深入解析ThreadLocal.pdf

    **ThreadLocal** 是Java提供的一个工具类,用于在**线程作用域内**创建和管理独立的变量副本。这意味着每个线程都有自己的变量副本,不会互相影响,从而实现了线程安全。 **ThreadLocal的使用场景** 1. **存储线程...

    java ThreadLocal使用案例详解

    Java ThreadLocal使用案例详解 Java ThreadLocal是Java语言中的一种机制,用于为每个线程提供一个独立的变量副本,以解决多线程环境下共享变量的线程安全问题。在本文中,我们将详细介绍Java ThreadLocal的使用案例...

    java 中ThreadLocal 的正确用法

    * ThreadLocal 变量应该是 private static 的,以避免外部访问和修改。 * 在使用 ThreadLocal 时,需要确保 initialValue() 方法的正确实现,以避免线程之间的数据共享。 * 在使用 ThreadLocal 时,需要注意避免内存...

    Java 中ThreadLocal类详解

    ThreadLocal并不是用来替代传统的同步机制(如synchronized关键字)的,而是提供了一种不同的并发控制策略。 ThreadLocal类的核心在于它的`set`、`get`和`remove`方法。`set`方法用于设置当前线程的ThreadLocal变量...

    入研究java.lang.ThreadLocal类.docx

    ### 知识点详解:Java.lang.ThreadLocal 类 #### 一、概述 **ThreadLocal** 并非线程的一种特殊实现形式,而是一种为每个线程...理解 ThreadLocal 的工作原理和应用场景对于编写高效可靠的多线程应用程序至关重要。

Global site tag (gtag.js) - Google Analytics