使线程具有有序性

正常情况下,线程在运行时多个线程之间执行任务的时机时无序的。可以通过改造代码的方式使它们运行具有有序性

  1. package Seven;
  2.  
  3. public class MyThread extends Thread {
  4.  
  5. private Object lock;
  6. private String showChar;
  7. private int showNumPosition;
  8.  
  9. private int printCount = 0;// 统计打印了几个字母
  10.  
  11. volatile private static int addNumber = 1;
  12.  
  13. public MyThread(Object lock, String showChar, int showNumPosition) {
  14. super();
  15. this.lock = lock;
  16. this.showChar = showChar;
  17. this.showNumPosition = showNumPosition;
  18. }
  19.  
  20. @Override
  21. public void run() {
  22. try {
  23. synchronized (lock) {
  24. while (true) {
  25. if (addNumber % 3 == showNumPosition) {
  26. System.out.println("ThreadName="
  27. + Thread.currentThread().getName()
  28. + " runCount=" + addNumber + " " + showChar);
  29. lock.notifyAll();
  30. addNumber++;
  31. printCount++;
  32. if (printCount == 3) {
  33. break;
  34. }
  35. } else {
  36. lock.wait();
  37. }
  38. }
  39. }
  40. } catch (InterruptedException e) {
  41. e.printStackTrace();
  42. }
  43.  
  44. }
  45.  
  46. }
  1. package Seven;
  2.  
  3. public class Run {
  4. public static void main(String[] args) {
  5.  
  6. Object lock = new Object();
  7.  
  8. MyThread a = new MyThread(lock, "A", 1);
  9. MyThread b = new MyThread(lock, "B", 2);
  10. MyThread c = new MyThread(lock, "C", 0);
  11.  
  12. a.start();
  13. b.start();
  14. c.start();
  15.  
  16. }
  17. }

SimpleDateFormat非线程安全

1在多线程环境下出现异常

  1. package Seven;
  2.  
  3. import java.text.ParseException;
  4. import java.text.SimpleDateFormat;
  5. import java.util.Date;
  6.  
  7. public class MyThread extends Thread {
  8.  
  9. private SimpleDateFormat sdf;
  10. private String dateString;
  11.  
  12. public MyThread(SimpleDateFormat sdf, String dateString) {
  13. super();
  14. this.sdf = sdf;
  15. this.dateString = dateString;
  16. }
  17.  
  18. @Override
  19. public void run() {
  20. try {
  21. Date dateRef = sdf.parse(dateString);
  22. String newDateString = sdf.format(dateRef).toString();
  23. if (!newDateString.equals(dateString)) {
  24. System.out.println("ThreadName=" + this.getName()+ "报错了 日期字符串:" + dateString + " 转换成的日期为:"+ newDateString);
  25. }
  26. } catch (ParseException e) {
  27. e.printStackTrace();
  28. }
  29.  
  30. }
  31.  
  32. }
  1. package Seven;
  2.  
  3. import java.text.SimpleDateFormat;
  4.  
  5. public class Test {
  6. public static void main(String[] args) {
  7.  
  8. SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
  9.  
  10. String[] dateStringArray = new String[] { "2000-01-01", "2000-01-02",
  11. "2000-01-03", "2000-01-04", "2000-01-05", "2000-01-06",
  12. "2000-01-07", "2000-01-08", "2000-01-09", "2000-01-10" };
  13.  
  14. MyThread[] threadArray = new MyThread[10];
  15. for (int i = 0; i < 10; i++) {
  16. threadArray[i] = new MyThread(sdf, dateStringArray[i]);
  17. }
  18. for (int i = 0; i < 10; i++) {
  19. threadArray[i].start();
  20. }
  21.  
  22. }
  23. }

2、解决异常方法1

  1. package Seven;
  2.  
  3. import java.text.ParseException;
  4. import java.text.SimpleDateFormat;
  5. import java.util.Date;
  6.  
  7. public class MyThread extends Thread {
  8.  
  9. private SimpleDateFormat sdf;
  10. private String dateString;
  11.  
  12. public MyThread(SimpleDateFormat sdf, String dateString) {
  13. super();
  14. this.sdf = sdf;
  15. this.dateString = dateString;
  16. }
  17.  
  18. @Override
  19. public void run() {
  20. try {
  21. Date dateRef = DateTools.parse("yyyy-MM-dd", dateString);
  22. String newDateString = DateTools.format("yyyy-MM-dd", dateRef).toString();
  23. if (!newDateString.equals(dateString)) {
  24. System.out.println("ThreadName=" + this.getName() + "报错了 日期字符串:" + dateString + " 转换成的日期为:"+ newDateString);
  25. }
  26. } catch (ParseException e) {
  27. e.printStackTrace();
  28. }
  29.  
  30. }
  31.  
  32. }
  1. package Seven;
  2.  
  3. import java.text.ParseException;
  4. import java.text.SimpleDateFormat;
  5. import java.util.Date;
  6.  
  7. public class DateTools {
  8. public static Date parse(String formatPattern, String dateString)
  9. throws ParseException {
  10. return new SimpleDateFormat(formatPattern).parse(dateString);
  11. }
  12.  
  13. public static String format(String formatPattern, Date date) {
  14. return new SimpleDateFormat(formatPattern).format(date).toString();
  15. }
  16.  
  17. }
  1. package Seven;
  2.  
  3. import java.text.SimpleDateFormat;
  4.  
  5. public class Test {
  6. public static void main(String[] args) {
  7.  
  8. SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
  9.  
  10. String[] dateStringArray = new String[] { "2000-01-01", "2000-01-02",
  11. "2000-01-03", "2000-01-04", "2000-01-05", "2000-01-06",
  12. "2000-01-07", "2000-01-08", "2000-01-09", "2000-01-10" };
  13.  
  14. MyThread[] threadArray = new MyThread[10];
  15. for (int i = 0; i < 10; i++) {
  16. threadArray[i] = new MyThread(sdf, dateStringArray[i]);
  17. }
  18. for (int i = 0; i < 10; i++) {
  19. threadArray[i].start();
  20. }
  21.  
  22. }
  23. }

解决的原理是创建了多个SimpleDateFormat类的实例

解决异常方法2

  1. package Seven;
  2.  
  3. import java.text.ParseException;
  4. import java.text.SimpleDateFormat;
  5. import java.util.Date;
  6.  
  7. public class MyThread extends Thread {
  8.  
  9. private SimpleDateFormat sdf;
  10. private String dateString;
  11.  
  12. public MyThread(SimpleDateFormat sdf, String dateString) {
  13. super();
  14. this.sdf = sdf;
  15. this.dateString = dateString;
  16. }
  17.  
  18. @Override
  19. public void run() {
  20. try {
  21. Date dateRef = DateTools.getSimpleDateFormat("yyyy-MM-dd").parse(dateString);
  22. String newDateString = DateTools.getSimpleDateFormat("yyyy-MM-dd").format(dateRef).toString();
  23. if (!newDateString.equals(dateString)) {
  24. System.out.println("ThreadName=" + this.getName()+ "报错了 日期字符串:" + dateString + " 转换成的日期为:"+ newDateString);
  25. }
  26. } catch (ParseException e) {
  27. e.printStackTrace();
  28. }
  29.  
  30. }
  31.  
  32. }
  1. package Seven;
  2.  
  3. import java.text.SimpleDateFormat;
  4.  
  5. public class DateTools {
  6. private static ThreadLocal<SimpleDateFormat> tl = new ThreadLocal<SimpleDateFormat>();
  7.  
  8. public static SimpleDateFormat getSimpleDateFormat(String datePattern) {
  9. SimpleDateFormat sdf = null;
  10. sdf = tl.get();
  11. if (sdf == null) {
  12. sdf = new SimpleDateFormat(datePattern);
  13. tl.set(sdf);
  14. }
  15. return sdf;
  16. }
  17. }
  1. package Seven;
  2.  
  3. import java.text.SimpleDateFormat;
  4.  
  5. public class Test {
  6. public static void main(String[] args) {
  7.  
  8. SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
  9.  
  10. String[] dateStringArray = new String[] { "2000-01-01", "2000-01-02",
  11. "2000-01-03", "2000-01-04", "2000-01-05", "2000-01-06",
  12. "2000-01-07", "2000-01-08", "2000-01-09", "2000-01-10" };
  13.  
  14. MyThread[] threadArray = new MyThread[10];
  15. for (int i = 0; i < 10; i++) {
  16. threadArray[i] = new MyThread(sdf, dateStringArray[i]);
  17. }
  18. for (int i = 0; i < 10; i++) {
  19. threadArray[i].start();
  20. }
  21.  
  22. }
  23. }

原理是ThreadLocal类能使线程绑定到指定的对象

《Java多线程编程核心技术》读后感(十七)的更多相关文章

  1. Java多线程编程核心技术---学习分享

    继承Thread类实现多线程 public class MyThread extends Thread { @Override public void run() { super.run(); Sys ...

  2. Java多线程编程核心技术---对象及变量的并发访问(二)

    数据类型String的常量池特性 在JVM中具有String常量池缓存的功能. public class Service { public static void print(String str){ ...

  3. Java多线程编程核心技术

    Java多线程编程核心技术 这本书有利于对Java多线程API的理解,但不容易从中总结规律. JDK文档 1. Thread类 部分源码: public class Thread implements ...

  4. 《Java多线程编程核心技术》推荐

    写这篇博客主要是给猿友们推荐一本书<Java多线程编程核心技术>. 之所以要推荐它,主要因为这本书写得十分通俗易懂,以实例贯穿整本书,使得原本抽象的概念,理解起来不再抽象. 只要你有一点点 ...

  5. 《java多线程编程核心技术》(一)使用多线程

    了解多线程 进程和多线程的概念和线程的优点: 提及多线程技术,不得不提及"进程"这个概念.百度百科对"进程"的解释如下: 进程(Process)是计算机中的程序 ...

  6. 《Java 多线程编程核心技术》- 笔记

    作为业务开发人员,能够在工作中用到的技术其实不多.虽然平时老是说什么,多线程,并发,注入,攻击!但是在实际工作中,这些东西不见得用得上.因为,我们用的框架已经把这些事做掉了. 比如web开发,外面有大 ...

  7. Thread.currentThread()和this的区别——《Java多线程编程核心技术》

    前言:在阅读<Java多线程编程核心技术>过程中,对书中程序代码Thread.currentThread()与this的区别有点混淆,这里记录下来,加深印象与理解. 具体代码如下: pub ...

  8. Java多线程编程核心技术(三)多线程通信

    线程是操作系统中独立的个体,但这些个体如果不经过特殊的处理就不能成为一个整体.线程间的通信就是成为整体的必用方案之一,可以说,使线程间进行通信后,系统之间的交互性会更强大,在大大提高CPU利用率的同时 ...

  9. Java多线程编程核心技术(二)对象及变量的并发访问

    本文主要介绍Java多线程中的同步,也就是如何在Java语言中写出线程安全的程序,如何在Java语言中解决非线程安全的相关问题.阅读本文应该着重掌握如下技术点: synchronized对象监视器为O ...

  10. Java多线程编程核心技术(一)Java多线程技能

    1.进程和线程 一个程序就是一个进程,而一个程序中的多个任务则被称为线程. 进程是表示资源分配的基本单位,线程是进程中执行运算的最小单位,亦是调度运行的基本单位. 举个例子: 打开你的计算机上的任务管 ...

随机推荐

  1. Hihocoder #1602 : 本质不同的回文子串的数量 manacher + BKDRhash

    #1602 : 本质不同的回文子串的数量 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 给定一个字符串S,请统计S的所有子串中,有多少个本质不同的回文字符串? 注意如果 ...

  2. JavaScript 原型解析

    1.什么是对象?     javascript中除了null和undefined之外都是Object的实例. 在Javascript中, 每定义一个函数, 将伴生一个原型对象. 原型就是用来为同一类对 ...

  3. 九度OJ 1161:Repeater(复制器) (递归)

    时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:1449 解决:508 题目描述: Harmony is indispensible in our daily life and no one ...

  4. c++动态绑定的技术实现

    1 什么是动态绑定 有一个基类,两个派生类,基类有一个virtual函数,两个派生类都覆盖了这个虚函数.现在有一个基类的指针或者引用,当该基类指针或者引用指向不同的派生类对象时,调用该虚函数,那么最终 ...

  5. json 数据返回解密

    http://www.cnhan.com/shantui//dynamic/get/data/allCompanyInfoByCompCode.json?compCode=6SU5YCJ <sc ...

  6. Python爬虫--Requests库

    Requests Requests是用python语言基于urllib编写的,采用的是Apache2 Licensed开源协议的HTTP库,requests是python实现的最简单易用的HTTP库, ...

  7. Android Development Note-02

    输入框左侧的logo:android:drawableleft   弹出提示: Toast.makeText(this,"提示",Toast.LENGHT_LONG).show() ...

  8. 使用wepy 小程序授权点击取消授权失败的方案

    在wepy里使用进行小程序页面授权,里面包含了用户点击取消的重新授权方案: //auth.js /* * @Author: Porco_Mar * @Date: 2018-04-11 15:49:55 ...

  9. 分布式任务调度平台XXL-Job搭建

    下载: https://github.com/xuxueli/xxl-job 下载 然后倒入到自己的工程里面 引入后: 导入数据:跑一边 导入: 修改: Window -->show view- ...

  10. Hadoop- Hadoop详解

    首先所有知识以官网为准,所有的内容在官网上都有展示,所有的变动与改进,新增内容都以官网为准.hadoop.apache.org Hadoop是一个开源的可拓展的分布式并行处理计算平台,利用服务器集群根 ...