Skip to content

Commit

Permalink
添加死锁示例
Browse files Browse the repository at this point in the history
  • Loading branch information
chenxinlei committed Aug 2, 2017
1 parent 7e59025 commit efa0d4c
Show file tree
Hide file tree
Showing 16 changed files with 491 additions and 0 deletions.
53 changes: 53 additions & 0 deletions src/main/java/com/shinley/thread/chapter7/lession1/Main.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package com.shinley.thread.chapter7.lession1;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.TimeUnit;

/**
* Created by shinley on 17-7-30.
*/
public class Main {
public static void main(String[] args) {
MyExecutor myExecutor = new MyExecutor(2, 4, 1000,
TimeUnit.MILLISECONDS, new LinkedBlockingDeque<Runnable>());
List<Future<String>> results = new ArrayList<>();

for (int i = 0; i < 10; i++) {
SleepTwoSecondsTask task = new SleepTwoSecondsTask();
Future<String> result = myExecutor.submit(task);
results.add(result);
}

for (int i = 0; i < 5; i++) {
try {
String result = results.get(i).get();
System.out.printf("Main: Result for Task %d : %s\n", i, result);
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}

myExecutor.shutdown();

for (int i = 5; i < 10; i++) {
try {
String result = results.get(i).get();
System.out.printf("Main: Result for Task %d : %s\n", i, result);
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}

try {
myExecutor.awaitTermination(1, TimeUnit.DAYS);
} catch (InterruptedException e) {
e.printStackTrace();
}

System.out.printf("Main: End of the program.\n");
}
}
60 changes: 60 additions & 0 deletions src/main/java/com/shinley/thread/chapter7/lession1/MyExecutor.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package com.shinley.thread.chapter7.lession1;

import java.util.Date;
import java.util.List;
import java.util.concurrent.*;

/**
* Created by shinley on 17-7-30.
*/
public class MyExecutor extends ThreadPoolExecutor{
private ConcurrentHashMap<String, Date> startTimes;

public MyExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit,
BlockingQueue<Runnable> workQueue) {

super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
startTimes=new ConcurrentHashMap<>();
}

@Override
public void shutdown() {
System.out.printf("MyExecutor: Going to shutdown.\n");
System.out.printf("MyExecutor: Executed tasks: %d\n",getCompletedTaskCount());
System.out.printf("MyExecutor: Running tasks: %d\n",getActiveCount());
System.out.printf("MyExecutor: Pending tasks: %d\n",getQueue().size());
super.shutdown();
}

@Override
public List<Runnable> shutdownNow() {
System.out.printf("MyExecutor: Going to immediately shutdown.\n");
System.out.printf("MyExecutor: Executed tasks: %d\n",getCompletedTaskCount());
System.out.printf("MyExecutor: Running tasks: %d\n",getActiveCount());
System.out.printf("MyExecutor: Pending tasks: %d\n",getQueue().size());
return super.shutdownNow();
}

@Override
protected void beforeExecute(Thread t, Runnable r) {
System.out.printf("MyExecutor: A task is beginning: %s : %s\n",t.getName(),r.hashCode());
startTimes.put(String.valueOf(r.hashCode()), new Date());
}

@Override
protected void afterExecute(Runnable r, Throwable t) {
Future<?> result=(Future<?>)r;
try {
System.out.printf("*********************************\n");
System.out.printf("MyExecutor: A task is finishing.\n");
System.out.printf("MyExecutor: Result: %s\n",result.get());
Date startDate=startTimes.remove(String.valueOf(r.hashCode()));
Date finishDate=new Date();
long diff=finishDate.getTime()-startDate.getTime();
System.out.printf("MyExecutor: Duration: %d\n",diff);
System.out.printf("*********************************\n");
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.shinley.thread.chapter7.lession1;

import java.util.Date;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;

/**
* Created by shinley on 17-7-30.
*/
public class SleepTwoSecondsTask implements Callable<String> {

@Override
public String call() throws Exception {
TimeUnit.SECONDS.sleep(2);
return new Date().toString();
}
}
Empty file.
22 changes: 22 additions & 0 deletions src/main/java/com/shinley/thread/chapter7/lession10/Main.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.shinley.thread.chapter7.lession10;

/**
* Created by shinley on 17-7-30.
*/
public class Main {
public static void main(String[] args) throws InterruptedException {
ParkingCounter counter=new ParkingCounter(5);
Sensor1 sensor1=new Sensor1(counter);
Sensor2 sensor2=new Sensor2(counter);
Thread thread1=new Thread(sensor1);
Thread thread2=new Thread(sensor2);
thread1.start();
thread2.start();

thread1.join();
thread2.join();

System.out.printf("Main: Number of cars: %d\n",counter.get());
System.out.printf("Main: End of the program.\n");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package com.shinley.thread.chapter7.lession10;

import java.util.concurrent.atomic.AtomicInteger;

/**
* Created by shinley on 17-7-30.
*/
public class ParkingCounter extends AtomicInteger {
private int maxNumber;

public ParkingCounter(int maxNumber) {
set(0);
this.maxNumber = maxNumber;
}

/**
* carIn()操作将实际汽车数与停车场(可容纳的汽车数)的最大值进行比较。如果它们相等,这辆汽车不能进行停车场并返回false值。
* 否则,它使用以下的原子操作结构:
* 1.用一个本地变量获取原子对象的值。
* 2.用一个不同的变量来存储新值。
* 3.使用compareAndSet()方法尝试将旧值替换成新值。如果这个方法返回true,作为参数传入的旧值是这个变量的值,因此,它使值变化。
* 随着carIn()方法返回true值,这个操作将以原子方式完成。如果compareAndSet()方法返回false值,
* 作为参数传入的旧值不是这个变量的值(其他线程已修改它),所以这个操作不能以原子方式完成。这个操作将重新开始,直到它可以以原子方式完成。
*
* @return
*/
public boolean carIn() {
for (; ; ) {
int value = get();
if (value == maxNumber) {
System.out.printf("ParkingCounter: The parking lot is full.\n");
return false;
} else {
int newValue = value + 1;
boolean changed = compareAndSet(value, newValue);
if (changed) {
System.out.printf("ParkingCounter: A car has entered.\n");
return true;
}
}
}
}

/**
* carOut()方法与carIn()方法类似。你已实现两个Runnable对象,使用carIn()和carOut()来模拟停车的活动。
* 当你执行这个程序,你可以看出停车场没有克服汽车在停车场的最大值。
*
* @return
*/
public boolean carOut() {
for (; ; ) {
int value = get();
if (value == 0) {
System.out.printf("ParkingCounter: The parking lot is empty.\n");
return false;
} else {
int newValue = value - 1;
boolean changed = compareAndSet(value, newValue);
if (changed) {
System.out.printf("ParkingCounter: A car has gone out.\n");
return true;
}
}
}
}
}
26 changes: 26 additions & 0 deletions src/main/java/com/shinley/thread/chapter7/lession10/Sensor1.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.shinley.thread.chapter7.lession10;

/**
* Created by shinley on 17-7-30.
*/
public class Sensor1 implements Runnable {
private ParkingCounter counter;

public Sensor1(ParkingCounter counter) {
this.counter=counter;
}

@Override
public void run() {
counter.carIn();
counter.carIn();
counter.carIn();
counter.carIn();
counter.carOut();
counter.carOut();
counter.carOut();
counter.carIn();
counter.carIn();
counter.carIn();
}
}
26 changes: 26 additions & 0 deletions src/main/java/com/shinley/thread/chapter7/lession10/Sensor2.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.shinley.thread.chapter7.lession10;

/**
* Created by shinley on 17-7-30.
*/
public class Sensor2 implements Runnable {

private ParkingCounter counter;

public Sensor2(ParkingCounter counter) {
this.counter=counter;
}

@Override
public void run() {
counter.carIn();
counter.carOut();
counter.carOut();
counter.carIn();
counter.carIn();
counter.carIn();
counter.carIn();
counter.carIn();
counter.carIn();
}
}
Empty file.
46 changes: 46 additions & 0 deletions src/main/java/com/shinley/thread/chapter7/lession2/Main.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package com.shinley.thread.chapter7.lession2;

import java.util.concurrent.PriorityBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
* 你已经实现了MyPriorityTask类,(作为一个任务)它实现了Runnable接口和Comparable接口,它被存储在优先级队列中。
* 这个类有一个Priority属性,用来存储任务的优先级。如果一个任务的这个属性有更高的值,它将被更早的执行。
* compareTo()方法决定任务在优先级列队中的顺序。在Main类,你提交8个不同优先级的任务给执行者。
* 你提交给执行者的第一个任务将第一个被执行。由于执行者闲置的,正在等待任务被执行,当第一个任务到达执行者时,执行者立即执行它们。
* 你已经创建有2个执行线程的执行者,所以,前两个任务将第一个被执行。然后,剩下的任务将按它们的优先级来执行。
*/
public class Main {
public static void main(String[] args) {
// 创建了两个执行线程的执行者
ThreadPoolExecutor executor = new ThreadPoolExecutor(2, 2, 1,
TimeUnit.SECONDS, new PriorityBlockingQueue<Runnable>());

for (int i = 0; i < 4; i++) {
MyPriorityTask task = new MyPriorityTask("Task " + i, i);
executor.execute(task);
}

try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}

for (int i = 4; i < 8; i++) {
MyPriorityTask task = new MyPriorityTask("Task " + i, i);
executor.execute(task);
}

executor.shutdown();

try {
executor.awaitTermination(1, TimeUnit.DAYS);
} catch (InterruptedException e) {
e.printStackTrace();
}

System.out.printf("Main: End of the program.\n");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package com.shinley.thread.chapter7.lession2;

import java.util.concurrent.TimeUnit;

/**
* Created by shinley on 17-7-30.
*/
public class MyPriorityTask implements Runnable, Comparable<MyPriorityTask> {

private int priority;

private String name;

public MyPriorityTask(String name, int priority) {
this.name = name;
this.priority = priority;
}

public int getPriority() {
return priority;
}

@Override
public void run() {
System.out.printf("MyPriorityTask: %s Priority : %d\n", name, priority);
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
}

@Override
public int compareTo(MyPriorityTask o) {
if (this.getPriority() < o.getPriority()) {
return 1;
}
if (this.getPriority() > o.getPriority()) {
return -1;
}
return 0;
}
}
Empty file.
Loading

0 comments on commit efa0d4c

Please sign in to comment.