线程不安全
SimpleDateFormat不是线程安全的
SimpleDateThread
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date; public class SimpleDateThread extends Thread {
private SimpleDateFormat sdf;
private String dateString;
public SimpleDateThread(SimpleDateFormat sdf,String dateString){
this.sdf=sdf;
this.dateString=dateString;
}
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);
}else{
System.out.println("ThreadName="+this.getName()+"转换正确 日期字符串:"+dateString+"转换成的日期为:"+newDateString);
}
} catch (ParseException e) {
e.printStackTrace();
}
}
}
SimpleDateDemo
import java.text.SimpleDateFormat; public class SimpleDateDemo {
public static void main(String[] args){
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
String[] dateStringArray=new String[]{"2000-01-01","2001-01-01","2002-01-01","2003-01-01","2004-01-01","2005-01-01","2006-01-01","2007-01-01","2008-01-01","2009-01-01"};
SimpleDateThread[] threadArray=new SimpleDateThread[10];
for(int i=0;i<10;i++){
threadArray[i]=new SimpleDateThread(sdf,dateStringArray[i]);
}
for(int i=0;i<10;i++){
threadArray[i].start();
}
}
}
运行结果
新增DateTools 类
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();
}
}
将SimpleDateThread中的代码替换
Date dateRef=DateTools.parse("yyyy-MM-dd",dateString);
String newDateString=DateTools.format("yyyy-MM-dd",dateRef).toString();
可解决线程不安全问题。
非阻塞队列
ConcurrentLinkedQueue
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; public class ConcurrentLinkedQueueTest {
private static ConcurrentLinkedQueue<Integer> queue=new ConcurrentLinkedQueue<Integer>();
private static int count=2;
private static CountDownLatch latch=new CountDownLatch(count); public static void main(String[] args) throws InterruptedException {
long timeStart=System.currentTimeMillis();
ExecutorService es= Executors.newFixedThreadPool(4);
ConcurrentLinkedQueueTest.offer();
for(int i=0;i<count;i++){
es.submit(new Poll());
}
latch.await();
System.out.println("cost time "+(System.currentTimeMillis()-timeStart)+"ms");
es.shutdown();
} public static void offer(){
for(int i=0;i<100000;i++){
queue.offer(i);
}
} static class Poll implements Runnable{ @Override
public void run() {
while (!queue.isEmpty()){
System.out.println(queue.poll());
}
latch.countDown();
}
}
}
阻塞队列
BlockingQueue
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingDeque; public class BlockingQueueTest {
public class Basket{
BlockingQueue<String> basket=new LinkedBlockingDeque<>(3); public void produce() throws InterruptedException{
basket.put("An apple");
} public String consume() throws InterruptedException{
return basket.take();
}
}
public class Producer implements Runnable{
private String instance;
private Basket basket; public Producer(String instance, Basket basket) {
this.instance = instance;
this.basket = basket;
} @Override
public void run() {
try {
while (true){
System.out.println("生产者准备生产苹果: "+instance);
basket.produce();
System.out.println("!生产者生产苹果完毕: "+instance);
Thread.sleep(300);
}
} catch (InterruptedException e) {
System.out.println("Producer Interrupted");
}
}
} public class Consumer implements Runnable{
private String instance;
private Basket basket; public Consumer(String instance, Basket basket) {
this.instance = instance;
this.basket = basket;
} @Override
public void run() {
try {
while (true){
System.out.println("消费者准备消费苹果: "+instance);
System.out.println(basket.consume());
System.out.println("!消费者消费苹果完毕: "+instance);
Thread.sleep(1000);
}
} catch (InterruptedException e) {
System.out.println("Consumer Interrupted");
}
}
}
public static void main(String[] args){
BlockingQueueTest test=new BlockingQueueTest();
Basket basket=test.new Basket();
ExecutorService service= Executors.newCachedThreadPool();
Producer producer=test.new Producer("生产者001",basket);
Producer producer1=test.new Producer("生产者002",basket);
Consumer consumer=test.new Consumer("消费者001",basket);
service.submit(producer);
service.submit(producer1);
service.submit(consumer);
}
}
并发工具类
CyclicBarrier
import java.util.Random;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; public class CyclicBarrierDemo {
public static void main(String[] args) throws Exception{
CyclicBarrier barrier=new CyclicBarrier(3);
ExecutorService service= Executors.newFixedThreadPool(3);
service.submit(new Thread(new Runner(barrier, "1号选手")));
service.submit(new Thread(new Runner(barrier, "2号选手")));
service.submit(new Thread(new Runner(barrier, "3号选手")));
service.shutdown();
}
static class Runner implements Runnable{
private CyclicBarrier barrier;
private String name; public Runner(CyclicBarrier barrier, String name) {
this.barrier = barrier;
this.name = name;
} @Override
public void run() {
try {
Thread.sleep(1000*(new Random()).nextInt(8));
System.out.println(name+" 准备好了...");
barrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
System.out.println(name+" 起跑!");
}
}
}
CountDownLatch
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; public class CountDownLatchDemo {
private static final int PLAYER_AMOUNT=5;
public static void main(String[] args){
CountDownLatchDemo demo=new CountDownLatchDemo();
demo.exec();
} public void exec(){
CountDownLatch begin=new CountDownLatch(1);
CountDownLatch end=new CountDownLatch(PLAYER_AMOUNT);
Player[] players=new Player[PLAYER_AMOUNT];
for(int i=0;i<PLAYER_AMOUNT;i++){
players[i]=new Player(i+1,begin,end);
}
ExecutorService service= Executors.newFixedThreadPool(PLAYER_AMOUNT);
System.out.println("Race begins!");
begin.countDown();
for(Player p:players){
service.execute(p);
}
try {
end.await();
} catch (Exception e) {
e.printStackTrace();
}finally {
System.out.println("Race ends!");
}
service.shutdown();
}
class Player implements Runnable{
private int id;
private CountDownLatch begin;
private CountDownLatch end; public Player(int id, CountDownLatch begin, CountDownLatch end) {
this.id = id;
this.begin = begin;
this.end = end;
} @Override
public void run() {
try {
begin.await();
Thread.sleep((long)(Math.random()*100));
System.out.println("Play"+id+" arrived.");
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
end.countDown();
}
}
}
}
Semaphore
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore; public class SemaphoreDemo {
public static void main(String[] args){
ExecutorService service= Executors.newCachedThreadPool();
final Semaphore semaphore=new Semaphore(5);
for(int i=0;i<20;i++){
final int no=i;
Runnable runnable=new Runnable() {
@Override
public void run() {
try {
semaphore.acquire();
System.out.println("Accessing: "+no);
Thread.sleep((long)(Math.random()*10000));
semaphore.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
service.execute(runnable);
}
service.shutdown();
}
}