• 《Java多线程编程核心技术》读后感(十七)


     

    使线程具有有序性

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

    package Seven;
    
    public class MyThread extends Thread {
    
        private Object lock;
        private String showChar;
        private int showNumPosition;
    
        private int printCount = 0;// 统计打印了几个字母
    
        volatile private static int addNumber = 1;
    
        public MyThread(Object lock, String showChar, int showNumPosition) {
            super();
            this.lock = lock;
            this.showChar = showChar;
            this.showNumPosition = showNumPosition;
        }
    
        @Override
        public void run() {
            try {
                synchronized (lock) {
                    while (true) {
                        if (addNumber % 3 == showNumPosition) {
                            System.out.println("ThreadName="
                                    + Thread.currentThread().getName()
                                    + " runCount=" + addNumber + " " + showChar);
                            lock.notifyAll();
                            addNumber++;
                            printCount++;
                            if (printCount == 3) {
                                break;
                            }
                        } else {
                            lock.wait();
                        }
                    }
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
    
        }
    
    }
    package Seven;
    
    public class Run {
        public static void main(String[] args) {
    
            Object lock = new Object();
    
            MyThread a = new MyThread(lock, "A", 1);
            MyThread b = new MyThread(lock, "B", 2);
            MyThread c = new MyThread(lock, "C", 0);
    
            a.start();
            b.start();
            c.start();
    
        }
    }

    SimpleDateFormat非线程安全

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

    package Seven;
    
    import java.text.ParseException;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    
    public class MyThread extends Thread {
    
        private SimpleDateFormat sdf;
        private String dateString;
    
        public MyThread(SimpleDateFormat sdf, String dateString) {
            super();
            this.sdf = sdf;
            this.dateString = dateString;
        }
    
        @Override
        public void run() {
            try {
                Date dateRef = sdf.parse(dateString);
                String newDateString = sdf.format(dateRef).toString();
                if (!newDateString.equals(dateString)) {
                    System.out.println("ThreadName=" + this.getName()+ "报错了 日期字符串:" + dateString + " 转换成的日期为:"+ newDateString);
                }
            } catch (ParseException e) {
                e.printStackTrace();
            }
    
        }
    
    
    }
    package Seven;
    
    import java.text.SimpleDateFormat;
    
    public class Test {
        public static void main(String[] args) {
    
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
    
            String[] dateStringArray = new String[] { "2000-01-01", "2000-01-02",
                    "2000-01-03", "2000-01-04", "2000-01-05", "2000-01-06",
                    "2000-01-07", "2000-01-08", "2000-01-09", "2000-01-10" };
    
            MyThread[] threadArray = new MyThread[10];
            for (int i = 0; i < 10; i++) {
                threadArray[i] = new MyThread(sdf, dateStringArray[i]);
            }
            for (int i = 0; i < 10; i++) {
                threadArray[i].start();
            }
    
        }
    }

    2、解决异常方法1

    package Seven;
    
    import java.text.ParseException;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    
    public class MyThread extends Thread {
    
        private SimpleDateFormat sdf;
        private String dateString;
    
        public MyThread(SimpleDateFormat sdf, String dateString) {
            super();
            this.sdf = sdf;
            this.dateString = dateString;
        }
    
        @Override
        public void run() {
            try {
                Date dateRef = DateTools.parse("yyyy-MM-dd", dateString);
                String newDateString = DateTools.format("yyyy-MM-dd", dateRef).toString();
                if (!newDateString.equals(dateString)) {
                    System.out.println("ThreadName=" + this.getName()    + "报错了 日期字符串:" + dateString + " 转换成的日期为:"+ newDateString);
                }
            } catch (ParseException e) {
                e.printStackTrace();
            }
    
        }
    
    }
    package Seven;
    
    import java.text.ParseException;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    
    public class DateTools {
        public static Date parse(String formatPattern, String dateString)
                throws ParseException {
            return new SimpleDateFormat(formatPattern).parse(dateString);
        }
    
        public static String format(String formatPattern, Date date) {
            return new SimpleDateFormat(formatPattern).format(date).toString();
        }
    
    }
    package Seven;
    
    import java.text.SimpleDateFormat;
    
    public class Test {
        public static void main(String[] args) {
    
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
    
            String[] dateStringArray = new String[] { "2000-01-01", "2000-01-02",
                    "2000-01-03", "2000-01-04", "2000-01-05", "2000-01-06",
                    "2000-01-07", "2000-01-08", "2000-01-09", "2000-01-10" };
    
            MyThread[] threadArray = new MyThread[10];
            for (int i = 0; i < 10; i++) {
                threadArray[i] = new MyThread(sdf, dateStringArray[i]);
            }
            for (int i = 0; i < 10; i++) {
                threadArray[i].start();
            }
    
        }
    }

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

    解决异常方法2

    package Seven;
    
    import java.text.ParseException;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    
    public class MyThread extends Thread {
    
        private SimpleDateFormat sdf;
        private String dateString;
    
        public MyThread(SimpleDateFormat sdf, String dateString) {
            super();
            this.sdf = sdf;
            this.dateString = dateString;
        }
    
        @Override
        public void run() {
            try {
                Date dateRef = DateTools.getSimpleDateFormat("yyyy-MM-dd").parse(dateString);
                String newDateString = DateTools.getSimpleDateFormat("yyyy-MM-dd").format(dateRef).toString();
                if (!newDateString.equals(dateString)) {
                    System.out.println("ThreadName=" + this.getName()+ "报错了 日期字符串:" + dateString + " 转换成的日期为:"+ newDateString);
                }
            } catch (ParseException e) {
                e.printStackTrace();
            }
    
        }
    
    }
    package Seven;
    
    import java.text.SimpleDateFormat;
    
    public class DateTools {
        private static ThreadLocal<SimpleDateFormat> tl = new ThreadLocal<SimpleDateFormat>();
    
        public static SimpleDateFormat getSimpleDateFormat(String datePattern) {
            SimpleDateFormat sdf = null;
            sdf = tl.get();
            if (sdf == null) {
                sdf = new SimpleDateFormat(datePattern);
                tl.set(sdf);
            }
            return sdf;
        }
    }
    package Seven;
    
    import java.text.SimpleDateFormat;
    
    public class Test {
        public static void main(String[] args) {
    
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
    
            String[] dateStringArray = new String[] { "2000-01-01", "2000-01-02",
                    "2000-01-03", "2000-01-04", "2000-01-05", "2000-01-06",
                    "2000-01-07", "2000-01-08", "2000-01-09", "2000-01-10" };
    
            MyThread[] threadArray = new MyThread[10];
            for (int i = 0; i < 10; i++) {
                threadArray[i] = new MyThread(sdf, dateStringArray[i]);
            }
            for (int i = 0; i < 10; i++) {
                threadArray[i].start();
            }
    
        }
    }

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

  • 相关阅读:
    检查.net代码中占用高内存函数(翻译)
    DataTable添加行和列
    使用.NET中的Action及Func泛型委托
    基于Emgu cv的图像拼接(转)
    AForge学习笔记(列表)
    标准Dispose实现 (转)
    在WPF程序中使用摄像头兼谈如何使用AForge.NET控件(转)
    NBearV3中文教程总目录
    如何在我们项目中利用开源的图表(js chart)
    1、NameNode启动流程的初始化操作
  • 原文地址:https://www.cnblogs.com/Michael2397/p/7860307.html
Copyright © 2020-2023  润新知