zoukankan      html  css  js  c++  java
  • 线程池的使用

    new Thread的弊端:

    1.不利于管理,线程的生产及销毁消耗资源,可能造成OOM。

    线程池的好处:

    1.统一管理,节约资源,并发控制

    package tcc.test.ConcurrentProgramming;

    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    import java.util.concurrent.Callable;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.Future;
    import java.util.concurrent.TimeUnit;

    /**
    * @author tcc:
    * @version 创建时间:2021年8月24日 上午11:04:29 类说明 Java通过Executors提供四种线程池,分别为:
    * newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
    * newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
    * newScheduledThreadPool 创建一个定长线程池,支持定时及周期性任务执行。
    * newSingleThreadExecutor 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。
    */
    public class FixedThreadPoolTest2 {
    // newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
    ExecutorService fixedThreadPool = Executors.newFixedThreadPool(2);
    /**
    * 超时时间/分钟
    */
    public static final int TIMEOUT = 5;

    public void testFixedThreadPool() {
    // 也知道callable和Runnable的区别是callable可以有返回值,也可以抛出异常的特性,而Runnable没有
    List<Callable<Boolean>> callableList = new ArrayList<Callable<Boolean>>();
    Callable<Boolean> call = new Callable<Boolean>() {
    @Override
    public Boolean call() throws Exception {
    try {
    return doYouMethod();
    } catch (Exception e) {
    System.out.println("执行异常:" + e);
    return null;
    }
    }
    };
    callableList.add(call);

    try {
    System.out.println("callableList==" + callableList);
    List<Future<Boolean>> futureList = fixedThreadPool.invokeAll(callableList);
    for (Future<Boolean> future : futureList) {
    Boolean flag = future.get(TIMEOUT, TimeUnit.MINUTES);
    if (flag) {
    System.out.println(" 成功");
    } else {
    System.out.println(" 失败");
    }
    }

    } catch (Exception e) {
    System.out.println(" ----- 异常 -----" + e.getMessage());
    }
    }

    public synchronized Boolean doYouMethod() {
    System.out.println(Thread.currentThread().getName());
    System.out.println("doYouMethod");
    return true;
    }

    public static void main(String[] args) {
    FixedThreadPoolTest2 ft = new FixedThreadPoolTest2();
    ft.testFixedThreadPool();
    }

    }

    具体使用场景:与其他系统的单点登录,并发量高时,使用线程池newFixedThreadPool 控制并发数,并且使用同步代码块保证线程安全。

    package com.sr.manager;

    import asp.engine.core.manager.BaseManager;
    import asp.engine.core.util.AspDaoUtil;
    import com.alibaba.fastjson.JSONObject;
    import com.sr.util.UserInfoUtils;
    import com.sr.util.UserInfoUtils_xfm;
    import com.util.DateUtils;
    import com.util.FieldList;
    import com.util.RowList;
    import com.web.frame.SSOClient;
    import jos.engine.core.ServiceData;
    import jos.engine.core.jdbc.JdbcTemplate;
    import jos.engine.encrypt.Encode;
    import jos.framework.key.KeyUtils;

    import java.util.ArrayList;
    import java.util.List;
    import java.util.concurrent.Callable;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.Future;
    import java.util.concurrent.TimeUnit;

    import org.apache.log4j.Logger;
    /**
    * @author tcc:
    * @version 创建时间:2021年8月24日 上午11:04:29 类说明 Java通过Executors提供四种线程池,分别为:
    * newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
    * newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
    * newScheduledThreadPool 创建一个定长线程池,支持定时及周期性任务执行。
    * newSingleThreadExecutor 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。
    */

    public class YhUserInfoManager extends BaseManager {
    ExecutorService fixedThreadPool = Executors.newFixedThreadPool(5);
    public static final int TIMEOUT = 5;

    @SuppressWarnings("unused")
    // 获取用户类型
    public void getUserInfoutype(ServiceData sdata) {
    String ticket = sdata.getRequest().getParameter("ticket");
    log.info("第一步:" + ticket);
    String result = UserInfoUtils.getUser(ticket);
    log.info("第二步:" + result);
    JSONObject json = JSONObject.parseObject(result);
    log.info("第三步:" + json);

    // 也知道callable和Runnable的区别是callable可以有返回值,也可以抛出异常的特性,而Runnable没有
    List<Callable<Boolean>> callableList = new ArrayList<Callable<Boolean>>();
    Callable<Boolean> call = new Callable<Boolean>() {
    @Override
    public Boolean call() throws Exception {
    try {
    return login(json, sdata);
    } catch (Exception e) {
    System.out.println("执行异常:" + e);
    return null;
    }
    }
    };
    callableList.add(call);

    try {
    System.out.println("callableList==" + callableList);
    List<Future<Boolean>> futureList = fixedThreadPool.invokeAll(callableList);
    for (Future<Boolean> future : futureList) {
    Boolean flag = future.get(TIMEOUT, TimeUnit.MINUTES);
    if (flag) {
    System.out.println(" 成功");
    } else {
    System.out.println(" 失败");
    }
    }

    } catch (Exception e) {
    System.out.println(" ----- 异常 -----" + e.getMessage());
    }

    }

    public synchronized Boolean login(JSONObject json, ServiceData sdata) {

    if ("0".equals(json.getString("result"))) {
    String name = json.getString("username");
    String userid = json.getString("userid");
    String gender = json.getString("sex");
    String usersfz = json.getString("idnum");
    String userTelephone = json.getString("telephone");
    String mobile = json.getString("mobile");

    String sql_user = "SELECT ukey,utype,userid FROM bd_user a WHERE usfz=? and uisuse=1 and uisdel=0";
    RowList rowList = getJdbcTemplate().queryRowList(sql_user, new Object[] { usersfz });

    // 多条数据救返回给前端多个类型
    if (rowList.size() > 1) {
    String utype = "";
    for (int i = 0; i < rowList.size(); i++) {
    FieldList field_user = rowList.get(i);
    utype = utype + "," + field_user.get("utype");
    }
    utype = utype.substring(1);
    sdata.setResponseBody("{success:"true",code:"01",msg:"登录成功",utype:'" + utype + "',sfz:'" + usersfz
    + "',ukey:'" + userid + "'}");
    return true;

    }

    // 只有一条数据,直接登录
    int size = rowList.size();
    String aString = rowList.get(0).get("userid");
    if (rowList.size() == 1 && rowList.get(0).get("userid") != "") {
    FieldList field_user = rowList.get(0);
    String utype = field_user.get("utype");
    String userid_zlj = field_user.get("userid");
    String up_ukey_sql = "update bd_user set ukey = ? where userid = ?";
    JdbcTemplate jdbcTemplate = new JdbcTemplate("mzdb");
    jdbcTemplate.startTransaction();
    userid = utype + "_" + userid;
    jdbcTemplate.executeUpdate(up_ukey_sql, new Object[] { userid, userid_zlj });
    jdbcTemplate.commitTransaction();
    String ssoParam = SSOClient.generateSSOParamTmp(userid);
    log.info("登录成功");
    log.info("登录认证参数:" + ssoParam);
    sdata.setResponseBody("{success:"true",code:"00",msg:"登录成功",ssoParam:'" + ssoParam + "',utype:'"
    + utype + "',sfz:'" + usersfz + "',pk_id:'" + userid + "'}");
    return true;
    }
    // 如果没有就直接新增
    String userpkid = String.valueOf(KeyUtils.nextId());
    String uxm = name;
    String username = "zww_" + mobile + "_" + userpkid;
    String utype = "999";
    String userpass = Encode.encodeToHex("sr123456");
    String ucjsj = DateUtils.formatDate("yyyy-MM-dd HH:mm:ss");
    String uxnode = "33";
    String usfz = usersfz;
    userid = utype + "_" + userid;
    String sql_insert = "INSERT INTO bd_user(userid, utype, uxm, username, userpass, ucjsj, uisshow, uisuse, uisdel, uxnode, uxid, ukey,usex,usfz,uphone,umobile) VALUES( "
    + userpkid + ", " + utype + ", '" + uxm + "', '" + username + "', '" + userpass + "', '" + ucjsj
    + "', 1, 1, 0, " + " '" + uxnode + "', '" + uxnode + "', '" + userid + "','" + gender + "', '"
    + usfz + "', '" + userTelephone + "', '" + mobile + "');";
    try {
    JdbcTemplate jdbcTemplate = new JdbcTemplate("mzdb");
    jdbcTemplate.startTransaction();
    jdbcTemplate.executeUpdate(sql_insert);
    jdbcTemplate.commitTransaction();

    String ssoParam = SSOClient.generateSSOParamTmp(userid);
    sdata.setResponseBody("{success:"true",code:"00",msg:"登录成功",ssoParam:'" + ssoParam + "',utype:'"
    + utype + "',sfz:'" + usersfz + "',pk_id:'" + userid + "'}");
    } catch (Exception e) {

    sdata.setResponseBody("{success:"true",code:"99",msg:"登录失败,请联系管理员!"}");
    return true;
    }
    } else {

    sdata.setResponseBody("{success:"true",code:"99",msg:"认证失败!"}");
    return true;
    }
    return true;

    }

    }

  • 相关阅读:
    企业使用数据库的12种姿势
    回归架构本质,重新理解微服务
    Java中随机数的产生方式与原理
    自动类型转换、强制类型转换、作用域、整型表数范围
    创建自定义类的对象数组
    CentOS上安装比较习惯的代码编辑器
    ubuntu 15.04 的安装遇到的问题及其解决方法
    算法思想篇(1)————枚举算法
    初来乍到
    Eclipse中获取html jsp 标签的属性提示信息方法
  • 原文地址:https://www.cnblogs.com/tongcc/p/15181851.html
Copyright © 2011-2022 走看看