Java--servlet + ThreadLocal解决多线程并发问题及实例

思维导图 – Servlet+ThreadLocal分包管理实例


一:本文思维导图
Java--servlet + ThreadLocal解决多线程并发问题及实例_第1张图片


二:ThreadLocal原理图
Java--servlet + ThreadLocal解决多线程并发问题及实例_第2张图片



三:代码:


实体层entity Book.java

package entity;

public class Book {
    /*私有属性*/
    private int id;
    private String name;
    private String author;
    private String publisher;
    private int price;

    /*默认构造函数*/
    public Book() {
        super();
    }

    public Book(String name, String author, String publisher, int price) {
        super();
        this.name = name;
        this.author = author;
        this.publisher = publisher;
        this.price = price;
    }

    public Book(int id, String name, String author, String publisher, int price) {
        super();
        this.id = id;
        this.name = name;
        this.author = author;
        this.publisher = publisher;
        this.price = price;
    }

    /*对象属性操作*/
    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

    public String getPublisher() {
        return publisher;
    }

    public void setPublisher(String publisher) {
        this.publisher = publisher;
    }

    public int getPrice() {
        return price;
    }

    public void setPrice(int price) {
        this.price = price;
    }
}

数据访问层data access object(dao)—BaseDao.java

package dao;

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

public class BaseDao {
    // 数据库驱动
    private static final String driver = "com.microsoft.sqlserver.jdbc.SQLServerDriver";

    // 连接数据库的url路径
    private static final String url = "jdbc:sqlserver://localhost:1433;DatabaseName=MyDB";

    // 用户名
    private static final String user = "sa";

    // 密码
    private static final String password = "sqlpass";

    // 在静态块中完成驱动的加载
    // 静态块中的业务逻辑在类加载器加载类的时候执行
    // 只会执行一次
    static {
        try {
            Class.forName(driver);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    protected Connection conn;

    protected PreparedStatement pstmt;

    protected ResultSet rs;

    // 该函数负责创建Connection对象
    protected void getConnection() {
        if (conn == null) {
            try {
                conn = DriverManager.getConnection(url, user, password);
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

    protected void getPreparedStatement(String sql) {
        if (conn == null) {
            getConnection();
        }
        try {
            pstmt = conn.prepareStatement(sql);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    // 该函数适合没有占位符的查询语句
    protected void getResultSet(String sql) {
        if (pstmt == null) {
            getPreparedStatement(sql);
        }

        try {
            rs = pstmt.executeQuery();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    protected void close() {

        if (rs != null) {
            try {
                rs.close();
                rs = null;
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

        if (pstmt != null) {
            try {
                pstmt.close();
                pstmt = null;
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

        if (conn != null) {
            try {
                conn.close();
                conn = null;
            } catch (SQLException e) {
                e.printStackTrace();
            }

        }

    }
}

dao层实例接口–IBookDao.java

package dao;

import java.util.ArrayList;

import entity.Book;

public interface IBookDao {
    public ArrayList queryBooksByPublihser(String publisher);
}

dao层接口实现 \impl\BookDaoImpl.java–

package dao.impl;

import dao.BaseDao;
import entity.Book;
import dao.IBookDao;

import java.sql.SQLException;
import java.util.ArrayList;

public class BookDaoImpl extends BaseDao implements IBookDao {
    @Override
    public ArrayList queryBooksByPublihser(String publisher) {

        ArrayList bookList = new ArrayList();
        String sql = "select * from tbook where publisher=?";
        getPreparedStatement(sql);
        try {
            pstmt.setString(1, publisher);
            rs = pstmt.executeQuery();
            /*循环读取数据*/
            while (rs.next()) {
                int id = rs.getInt("id");
                String name = rs.getString("name");
                String author = rs.getString("author");
                String publisherval = rs.getString("publisher");
                int price = rs.getInt("price");

                Book book = new Book(id, name, author, publisherval, price);
                bookList.add(book);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            // 释放连接资源
            close();
        }
        /*返回bookList*/
        return bookList;
    }
}

本文精华Mark:线程池 – datasource\ThreadLocalData.java

package datasource;

import dao.*;
import service.*;

public class ThreadLocalData {
    //与控制层相连,静态对象
    public static ThreadLocal threadLocalBookService = new ThreadLocal();
    //与业务逻辑层相连,静态对象
    public static ThreadLocal threadLocalBookDao = new ThreadLocal();
}

业务逻辑层service – IBookService接口

package service;

import java.util.ArrayList;

import entity.Book;

public interface IBookService {
    public ArrayList queryBooksByPublihser(String publisher);
}

本文精华Mark:业务逻辑层service – BookServiceImpl接口的实现

package service.impl;

import java.util.ArrayList;

import dao.IBookDao;
import dao.impl.BookDaoImpl;
import datasource.ThreadLocalData;

import entity.Book;

import service.IBookService;

public class BookServiceImpl implements IBookService {
    @Override
    public ArrayList queryBooksByPublihser(String publisher) {

        IBookDao bookDao;
        //在线程池中获取key-value的键值,不存在新建threadLocal对象
        if (ThreadLocalData.threadLocalBookDao.get() == null) {

            bookDao = new BookDaoImpl();

            ThreadLocalData.threadLocalBookDao.set(bookDao);

        }
        //从threadLocal对象中取值
        bookDao = ThreadLocalData.threadLocalBookDao.get();
        //返回BookList列表
        return bookDao.queryBooksByPublihser(publisher);
    }

}

本文精华Mark:控制层control control\BookServlet.java

package control;

import java.awt.print.Book;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import datasource.ThreadLocalData;
import service.IBookService;
import service.impl.BookServiceImpl;

@SuppressWarnings("serial")
public class BookServlet extends HttpServlet {
    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        /*中文编码UTF-8*/
        request.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=utf-8");
        PrintWriter out = response.getWriter();

        String publisher = request.getParameter("publisher");

        /*Book接口对象service*/
        IBookService bookService;
        /*如果线程池中找不到实例对象,则新建*/
        if (ThreadLocalData.threadLocalBookService.get() == null) {
            bookService = new BookServiceImpl();
            ThreadLocalData.threadLocalBookService.set(bookService);
        }
        /*从线程池中取值*/
        bookService = ThreadLocalData.threadLocalBookService.get();
        /*bookService调用queryBookByPublisher方法后返回BookList列表*/
        ArrayList.Book> books = bookService.queryBooksByPublihser(publisher);
        /*绑定对象*/
        request.setAttribute("books", books);

        /*重定向*/     request.getRequestDispatcher("/result.jsp").forward(request, response);

        out.flush();
        out.close();
    }
}

result.jsp [JSTL库]

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>


<html>
  <head>
    <base href="<%=basePath%>">

    <title>My JSP 'result.jsp' starting pagetitle>

    <meta http-equiv="pragma" content="no-cache">
    <meta http-equiv="cache-control" content="no-cache">
    <meta http-equiv="expires" content="0">    
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    <meta http-equiv="description" content="This is my page">
    
    <style type="text/css">
        div{
            width:800px;
            height: 600px;
            margin:0 auto;
        }
    style>
  head>

  <body>
    <div>
        <h1>查询结果h1>
    <table width="600px" border="1px">
        <tr>
            <td>IDtd>
            <td>NAMEtd>
            <td>AUTHORtd>
            <td>PUBLISHERtd>
            <td>PRICEtd>
        tr>
        <c:forEach items="${requestScope.books}" var="book">
            <tr>
                <td>${book.id}td>
                <td>${book.name}td>
                <td>${book.author}td>
                <td>${book.publisher}td>
                <td>${book.price}td>
            tr>
        c:forEach>
    table>
    div>
  body>
html>

四:小结

1)服用方式:结合前篇博文一起服用,记得参考思维导图,效果更佳;
2)有效日期:2XXX-XX-XX;
3)详情咨询:[email protected] 欢迎打扰;
4)版权所有:如有雷同,纯属巧合;
5)如何修改:如有更好的实现方法或者实例,请fork;
6)本人撰博纯属巧合;
7)如有不足之处,提出必改正;
8)后续内容:Ajax[异步js and xml]引擎访问数据数内容;
9)附上层与层之间的逻辑图[request,response],请参见下图;
Java--servlet + ThreadLocal解决多线程并发问题及实例_第3张图片

你可能感兴趣的:(IT学习,Java)