zoukankan      html  css  js  c++  java
  • DRP之synchronized及锁的思考

       写这篇博文的背景,是发生在前段时间的评教系统,评教系统出现瘫痪,为了找出问题,大家加班加点,找出的问题就是一个字:“锁”,由于评教系统会频繁的出现学生对数据库的查询,修改,查询,修改,这样就产生了一个进程资源不够,产生死锁!

       在进行DRP项目中,id生成器的原理与我原先评教系统的机制是大致相同的,id加1,然后接着查询id,反复进行此操作,如果一个人,小数据量的在进行,系统不会报错,但是,米老师一直提出“大数据”,我们做出的软件不是一个人在使用。如何避免这样的问题。看下面的代码:

      

    package com.bjpowernode.drp.util;
    
    import java.sql.Connection;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    
    /**
     * id生成器
     * @author Administrator
     *
     */
    public class IdGenerator {
    
    	/**
    	 * 根据表名生成该表的序列
    	 * @param tableName
    	 * @return 返回生成的序列
    	 */
    	<span style="color:#ff0000;">//public static synchronized int generate(String tableName) {
    	//public synchronized int generate(String tableName) {
    		//synchronized(this) {</span>
    	public static int generate(String tableName) {
    		//使用数据库的悲观锁for update
    		<span style="color:#ff0000;">String sql = "select value from t_table_id where table_name=? for update";</span>
    		Connection conn = null;
    		PreparedStatement pstmt = null;
    		ResultSet rs = null;
    		int value = 0;
    		try {
    			conn = DbUtil.getConnection();
    			//开始事务
    			DbUtil.beginTransaction(conn);
    			pstmt = conn.prepareStatement(sql);
    			pstmt.setString(1, tableName);
    			rs = pstmt.executeQuery();
    			if (!rs.next()) {
    				throw new RuntimeException();
    			}
    			value = rs.getInt("value");
    			value++; //自加
    			modifyValueField(conn, tableName, value);
    			//提交事务
    			DbUtil.commitTransaction(conn);
    		}catch(Exception e) {
    			e.printStackTrace();
    			//回滚事务
    			DbUtil.rollbackTransaction(conn);
    			throw new RuntimeException();
    		}finally {
    			DbUtil.close(rs);
    			DbUtil.close(pstmt);
    			DbUtil.resetConnection(conn); //重置Connection的状态
    			DbUtil.close(conn);
    		}
    		return value;
    	}
    	
    	/**
    	 * 根据表名更新序列字段的值
    	 * @param conn
    	 * @param tableName
    	 * @param value
    	 */
    	private static void modifyValueField(Connection conn, String tableName, int value) 
    	throws SQLException {
    		String sql = "update t_table_id set value=? where table_name=?";
    		PreparedStatement pstmt = null;
    		try {
    			pstmt = conn.prepareStatement(sql);
    			pstmt.setInt(1, value);
    			pstmt.setString(2, tableName);
    			pstmt.executeUpdate();
    		}finally {
    			DbUtil.close(pstmt);
    		}
    	} 
    	
    	public static void main(String[] args) {
    		int retValue = IdGenerator.generate("t_client");
    		System.out.println(retValue);
    	}
    }
        请看上面代码中红色部分,static synchronized与synchronized以及synchronized(this)的区别(如果大家想看详细的介绍请看柳波师哥的博客点击打开链接):

       1.synchronized static是某个类的范围,synchronized static 防止多个线程同时访问这个 类中的synchronized static 方法。它可以对类的所有对象实例起作用。 synchronized 是某实例的范围,synchronized 防止多个线程同时访问这个实例中的synchronized 方法。
       2.synchronized方法与synchronized(this)代码快的区别
            synchronized methods(){} 与synchronized(this){}之间没有什么区别,只是synchronized methods(){} 便于阅读理解,而synchronized(this){}可以更精确的控制冲突限制访问区域,有时候表现更高效率。
       3.synchronized关键字是不能继承的

        这里我想说一下关于死锁出现的情况以及解决的方案,大家看我的代码中红色的查询语句,

        我在cmd窗口中实验了一下:


      回车以后是没有提交数据的!


       在另一个cmd窗口中,看看在红色区域是没有任何数据的!


      出现上面的原因是在第一个窗口中锁住了数据库

      那么第二个cmd窗口如何访问数据呢,在第一个窗口中提交事务或者回滚实务如下图:


      当提交完成后在第二个窗口中就会自动出现下图:


         上面在查询语句中加入了一个for update 这叫做悲观锁。

        锁的概念在软考,操作系统,进程,线程和我们最近的评教系统中,都运用到了,如果将来以后做大数据,我相信锁的运用更是必不可少的!

    
       
    
    
  • 相关阅读:
    为图片指定区域添加链接
    数值取值范围问题
    【leetcode】柱状图中最大的矩形(第二遍)
    【leetcode 33】搜索旋转排序数组(第二遍)
    【Educational Codeforces Round 81 (Rated for Div. 2) C】Obtain The String
    【Educational Codeforces Round 81 (Rated for Div. 2) B】Infinite Prefixes
    【Educational Codeforces Round 81 (Rated for Div. 2) A】Display The Number
    【Codeforces 716B】Complete the Word
    一个简陋的留言板
    HTML,CSS,JavaScript,AJAX,JSP,Servlet,JDBC,Structs,Spring,Hibernate,Xml等概念
  • 原文地址:https://www.cnblogs.com/xzpblog/p/5117948.html
Copyright © 2011-2022 走看看