很多时候并发需要考虑线程安全,但也有很多时候和线程安全毛关系都没有,因为并发最大的作用是并行,线程安全仅仅是并发的一个子话题。

例如常常会用于并发运算,并发i/o。

下文是一个练习笔记。

运行环境:windows 11,jdk17

1.Pojo--StudentExamScoreSummary

package study.model.school;

import java.math.BigDecimal;
import java.util.Date; public class StudentExamScoreSummary implements Comparable<StudentExamScoreSummary>{
private Integer id;
private Integer studentId;
private Integer theYear;
private BigDecimal lanScore;
private BigDecimal mathScore;
private BigDecimal physicalScore;
private BigDecimal politicsScore;
private BigDecimal philosophyScore;
private BigDecimal avgScore;
private Date optime; public Integer getId() {
return id;
} public void setId(Integer id) {
this.id = id;
} public Integer getStudentId() {
return studentId;
} public void setStudentId(Integer studentId) {
this.studentId = studentId;
} public Integer getTheYear() {
return theYear;
} public void setTheYear(Integer theYear) {
this.theYear = theYear;
} public BigDecimal getLanScore() {
return lanScore;
} public void setLanScore(BigDecimal lanScore) {
this.lanScore = lanScore;
} public BigDecimal getMathScore() {
return mathScore;
} public void setMathScore(BigDecimal mathScore) {
this.mathScore = mathScore;
} public BigDecimal getPhysicalScore() {
return physicalScore;
} public void setPhysicalScore(BigDecimal physicalScore) {
this.physicalScore = physicalScore;
} public BigDecimal getPoliticsScore() {
return politicsScore;
} public void setPoliticsScore(BigDecimal politicsScore) {
this.politicsScore = politicsScore;
} public BigDecimal getPhilosophyScore() {
return philosophyScore;
} public void setPhilosophyScore(BigDecimal philosophyScore) {
this.philosophyScore = philosophyScore;
} public BigDecimal getAvgScore() {
return avgScore;
} public void setAvgScore(BigDecimal avgScore) {
this.avgScore = avgScore;
} public Date getOptime() {
return optime;
} public void setOptime(Date optime) {
this.optime = optime;
} public BigDecimal calAvgScore() {
return (this.lanScore.add(this.mathScore).add(this.physicalScore).add(this.politicsScore)
.add(this.philosophyScore)).divide(new BigDecimal(5));
} @Override
public int compareTo(StudentExamScoreSummary o) {
return this.avgScore.compareTo(o.getAvgScore());
} }

2.线程和测试代码-ConcurrentListRunable


/**
*
*/
package study.base.types.collection.list; import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.TreeSet; import study.model.school.StudentExamScoreSummary; /**
* @author luzhifei
*
*/
public class ConcurrentListRunable implements Runnable { private List<StudentExamScoreSummary> scoreList;
private Map<String, Boolean> flag; public ConcurrentListRunable(List<StudentExamScoreSummary> list, Map<String, Boolean> flag) {
this.scoreList = list;
this.flag = flag;
} @Override
public void run() {
int len = scoreList.size();
String courseName = Thread.currentThread().getName();
for (int i = 0; i < len; i++) {
StudentExamScoreSummary item = scoreList.get(i);
double rscore = Math.random() * 100;
BigDecimal dScore = new BigDecimal(rscore);
dScore.setScale(1, RoundingMode.HALF_UP);
synchronized (scoreList) {
switch (courseName) {
case "语文":
item.setLanScore(dScore);
break;
case "数学":
item.setMathScore(dScore);
break;
case "物理":
item.setPhysicalScore(dScore);
break;
case "政治":
item.setPoliticsScore(dScore);
break;
case "哲学":
item.setPhilosophyScore(dScore);
break;
}
} try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
flag.put(courseName, true);
} public static void main(String[] args) {
int tty = 10;
String[] courses = new String[] { "数学", "语文", "物理", "政治", "哲学" };
Map<String, Boolean> flag = new HashMap<String, Boolean>(5);
for (int i = 0; i < courses.length; i++) {
flag.put(courses[i], false);
} List<StudentExamScoreSummary> sList = new ArrayList<StudentExamScoreSummary>();
for (int i = 0; i < tty; i++) {
StudentExamScoreSummary score = new StudentExamScoreSummary();
score.setId(i);
score.setStudentId(i);
score.setTheYear(2024);
sList.add(score);
}
List<StudentExamScoreSummary> conList = Collections.synchronizedList(sList);
ConcurrentListRunable job = new ConcurrentListRunable(conList, flag); List<Thread> jobs = new ArrayList<>();
for (int i = 0; i < courses.length; i++) {
Thread t = new Thread(job, courses[i]);
jobs.add(t);
} for (int i = 0; i < courses.length; i++) {
jobs.get(i).start();
} boolean isDone = false;
while (isDone == false) {
isDone = true;
for (int i = 0; i < courses.length; i++) {
if (flag.get(courses[i]) == false) {
isDone = false;
break;
}
}
} DecimalFormat df = new DecimalFormat("#00.0");
for (int i = 0; i < sList.size(); i++) {
StudentExamScoreSummary item = sList.get(i);
BigDecimal avgScore = item.calAvgScore();
item.setAvgScore(avgScore);
String scoreTxt = item.getStudentId().toString() + "-【语文】" + df.format(item.getLanScore()) + " 【数学】"
+ df.format(item.getMathScore()) + " 【物理】" + df.format(item.getPhysicalScore()) + " 【政治】"
+ df.format(item.getPoliticsScore()) + " 【哲学】" + df.format(item.getPhilosophyScore()) + " |平均成绩:"
+ df.format(avgScore);
System.out.println(scoreTxt);
} // 排序
System.out.println("排序------------------------------------------");
TreeSet<StudentExamScoreSummary> ts = new TreeSet<StudentExamScoreSummary>(sList); for (Iterator<StudentExamScoreSummary> iter = ts.iterator(); iter.hasNext();) {
StudentExamScoreSummary item = iter.next();
System.out.println(item.getStudentId().toString() + " 平均成绩:" + df.format(item.getAvgScore()));
}
} }

测试结果1:

0-【语文】94.6 【数学】67.6 【物理】38.0 【政治】47.2 【哲学】35.3   |平均成绩:56.5
1-【语文】23.2 【数学】89.8 【物理】70.7 【政治】68.9 【哲学】49.3   |平均成绩:60.4
2-【语文】36.6 【数学】19.1 【物理】21.8 【政治】36.4 【哲学】75.6   |平均成绩:37.9
3-【语文】89.6 【数学】14.4 【物理】44.4 【政治】80.6 【哲学】07.1   |平均成绩:47.2
4-【语文】82.0 【数学】18.2 【物理】70.2 【政治】63.9 【哲学】17.4   |平均成绩:50.4
5-【语文】27.4 【数学】04.2 【物理】37.7 【政治】17.8 【哲学】20.1   |平均成绩:21.5
6-【语文】10.5 【数学】64.8 【物理】68.7 【政治】21.0 【哲学】97.2   |平均成绩:52.4
7-【语文】12.4 【数学】98.9 【物理】95.8 【政治】03.7 【哲学】56.3   |平均成绩:53.4
8-【语文】40.3 【数学】48.7 【物理】53.7 【政治】61.4 【哲学】42.9   |平均成绩:49.4
9-【语文】70.1 【数学】39.3 【物理】41.6 【政治】77.6 【哲学】87.3   |平均成绩:63.2
排序------------------------------------------
5 平均成绩:21.5
2 平均成绩:37.9
3 平均成绩:47.2
8 平均成绩:49.4
4 平均成绩:50.4
6 平均成绩:52.4
7 平均成绩:53.4
0 平均成绩:56.5
1 平均成绩:60.4
9 平均成绩:63.2

注意事项:

1.StudentExamScoreSummary必须实现Comparable接口,因为测试代码使用TreeSet

TreeSet<StudentExamScoreSummary> ts = new TreeSet<StudentExamScoreSummary>(sList); 
以上代码调用的构造函数是:
public TreeSet(Collection<? extends E> c) {
        this();
        addAll(c);
    }
这个构造函数要求入参必须实现Comparable接口(如果参数不是简单的java类型)。

2.Collections.synchronizedList的结果要求手动调用sychronized

   否则可能会线程不安全。

3.代码仅仅是为了演示使用5个线程各自生成成绩,不考虑效率问题。高效且正确的做法应该是分别计算5个不相干的List。

我们需要使用并发list的时候,正常情况下,多数是因为以下理由:

  • 对list的操作仅仅占据了很少的计算资源,线程更多的时候是做其它更耗费资源的事情
  • 为了实现异步操作

java并发和排序的简单例子(Runnable+TreeSet)的更多相关文章

  1. Java并发(10)- 简单聊聊JDK中的七大阻塞队列

    引言 JDK中除了上文提到的各种并发容器,还提供了丰富的阻塞队列.阻塞队列统一实现了BlockingQueue接口,BlockingQueue接口在java.util包Queue接口的基础上提供了pu ...

  2. Java并发:ThreadLocal的简单介绍

    作者:汤圆 个人博客:javalover.cc 前言 前面在线程的安全性中介绍过全局变量(成员变量)和局部变量(方法或代码块内的变量),前者在多线程中是不安全的,需要加锁等机制来确保安全,后者是线程安 ...

  3. [Java Web] 4、JavaScript 简单例子(高手略过)

    内容概览: JavaScript简介 JavaScript的基本语法 JavaScript的基本应用 JavaScript的事件处理 window对象的使用 JavaScript简介: JavaScr ...

  4. 【Java】Java日志框架Logback的简单例子

    常用的日志框架 SLF4J,全称Simple Logging Facade for Java,即Java简单日志外观框架,顾名思义,它并非具体的日志实现,而是日志外观框架 java.util.logg ...

  5. [转载]使用java.lang.Process类的简单例子

    FROM: http://segmentfault.com/blog/lidonghao/1190000000372192 ProcessBuilder类是J2SE 1.5在java.lang中新添加 ...

  6. rabbit的简单搭建,java使用rabbitmq queue的简单例子和一些坑

    一 整合 由于本人的码云太多太乱了,于是决定一个一个的整合到一个springboot项目里面. 附上自己的项目地址https://github.com/247292980/spring-boot 以整 ...

  7. Java连接数据库 #07# MyBatis Generator简单例子

    MyBatis Generator是一个可以帮助我们免去手写实体类&接口类以及XML的代码自动生成工具. 下面,通过一个简单的例子介绍MyBatis Generator如何使用. 大体流程如下 ...

  8. java并发:AQS的简单理解

    简介: AQS全称 AbstractQueuedSynchronizer,提供了一个基于FIFO(先进先出)队列,可以用于构建锁或者其他相关同步装置的基础框架. ReentrantLock.Semap ...

  9. Java产生死锁的一个简单例子

    思路是创建两个字符串a和b,再创建两个线程A和B,让每个线程都用synchronized锁住字符串(A先锁a,再去锁b:B先锁b,再锁a),如果A锁住a,B锁住b,A就没办法锁住b,B也没办法锁住a, ...

  10. JAVA JDBC 增删改查简单例子

    1.数据库配置文件jdbc.properties driver=com.mysql.jdbc.Driver url=jdbc:mysql://localhost:3306/test username= ...

随机推荐

  1. 尝试 IIncrementalGenerator 进行增量 Source Generator 生成代码

    在加上热重载时,源代码生成 Source Generator 的默认行为会让 Visual Studio 有些为难,其原因是热重载会变更代码,变更代码触发代码生成器更新代码,代码生成器更新的代码说不定 ...

  2. WPF 使用 VisualBrush 在 4k 加 200 DPI 设备上某些文本不渲染看不见问题

    这是我做一个十万点实时刷新的图表控件遇到的问题,做过高性能图表的伙伴大概都知道,此时需要关闭命中测试的功能,无论是控件的还是 Drawing 的,否则计算命中测试的耗时将会让主线程卡住.为了解决此问题 ...

  3. github只下载某个文件或文件夹(使用GitZip插件)

    安装GitZip插件 (此安装过程需要梯子(不懂"梯子",百度一下就明白)) 1. 打开插件管理页面 方法一:打开Chrome浏览器(Edge浏览器同理),在Chrom地址栏输入c ...

  4. SAP集成技术(五)集成风格

    上一节介绍了各种集成架构,这一节将介绍各种集成风格(Style).我们在日常工作中使用这些集成风格来分类不同类型的集成场景.本文将遵循SAP的集成解决方案咨询方法(ISA - M)使用的方法,将集成风 ...

  5. dotnet build error CS5001: Program does not contain a static 'Main' method suitable for an entry point

    前言 Docker环境编译.Net6项目,出现诡异的CS5001 Program does not contain a static 'Main' method suitable for an ent ...

  6. AI实战 | 手把手带你打造智能待办助手

    背景 大家好,我是努力的小雨.今天我想分享一下搭建待办助手的经历.起初,我并没有什么特别的创意点子.但在4月16日的百度Create大会上,我看到了小度的大模型加持使得其变得更加智能.我被一场示例所震 ...

  7. 面向教师的OBS直播速成教程

    引言 本文是面向教师讲述的如何使用OBS软件进行课程直播的速成教程. 本文配套视频链接如下️ 面向教师的OBS直播教学速成教程_哔哩哔哩_bilibili 环境准备 1. 下载对应本机系统版本的并安装 ...

  8. 用Python画一个冰墩墩!

    北京2022年冬奥会的召开,吉祥物冰墩墩着实火了,真的是一墩难求,为了实现冰墩墩的自由,经过资料搜集及参考冰墩墩网上的开源代码(https://github.com/HelloCoder-HaC/bi ...

  9. HH的项链——题解

    题目描述 直接求解会导致不同贝壳在上个区间算过但这个区间没标记的情况,所以在求解时要把上个区间的标记转移到这个区间 转移前先右边界由小到大排序,然后转移上个右边界到这个右边界的标记,同时记录上个标记出 ...

  10. mybatisplus 中查询的实体对应的表名是动态的解决方案

    开发中遇到需要查询一些表里的数据,这些数据按照一定的规则存放在不同的数据库表里,例如表名是table_name+月份  table_name_2024_05,table_name_2024_04这样, ...