使线程具有有序性
正常情况下,线程在运行时多个线程之间执行任务的时机时无序的。可以通过改造代码的方式使它们运行具有有序性
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类能使线程绑定到指定的对象