汪文君高并发编程总结-第一阶段
例子1-线程的创建
public class TryConcurrency {
public static void main(String[] args) {
Thread t = new Thread("READ-Thread") {
@Override
public void run() {
println(Thread.currentThread().getName());//main
readFromDataBase();
}
};
t.start();
new Thread("WRITE-Thread") {
@Override
public void run() {
writeDataToFile();
}
}.start();
}
private static void readFromDataBase() {
//read data from database and handle it.
try {
println("Begin read data from db.");
Thread.sleep(1000 * 30L);
println("Read data done and start handle it.");
} catch (InterruptedException e) {
e.printStackTrace();
}
println("The data handle finish and successfully.");
}
private static void writeDataToFile() {
try {
println("Begin write data to file.");
Thread.sleep(2000 * 20L);
println("Write data done and start handle it.");
} catch (InterruptedException e) {
e.printStackTrace();
}
println("The data handle finish and successfully.");
}
private static void println(String message) {
System.out.println(message);
}
}
例子2-Tread类的模板方法
public class TemplateMethod {
public final void print(String message) {
System.out.println("################");
wrapPrint(message);
System.out.println("################");
}
protected void wrapPrint(String message) {
}
public static void main(String[] args) {
TemplateMethod t1 = new TemplateMethod(){
@Override
protected void wrapPrint(String message) {
System.out.println("*"+message+"*");
}
};
t1.print("Hello Thread");
TemplateMethod t2 = new TemplateMethod(){
@Override
protected void wrapPrint(String message) {
System.out.println("+"+message+"+");
}
};
t2.print("Hello Thread");
}
}
1.Java应用程序的main函数是一个线程,是被JVM启动的时候调用,线程的名字叫main
2.实现一个线程,必须创建Thread实例,override run方法,并且调用start方法
3.在jvm启动后实际上有多个线程,但是至少有一个非守护线程
4.当你调用一个线程start方法的时候,此时至少有两个线程,一个是调用你的线程,还有一个是启动的线程
5.线程的生命周期分为new,runnable,running,block,terminated
例子3
多线程银行窗口排号的例子
- 版本V1
public class TicketWindow extends Thread {
private String name;
private final static Integer MAX = 50;
private Integer i = 1;
public TicketWindow(String name ) {
this.name = name;
}
@Override
public void run() {
while (i <= MAX) {
System.out.println(name+"号码为:"+i++);
}
}
}
public class Back {
public static void main(String[] args) {
TicketWindow t1 = new TicketWindow("窗口1");
t1.start();
TicketWindow t2 = new TicketWindow("窗口2");
t2.start();
TicketWindow t3 = new TicketWindow("窗口3");
t3.start();
}
}
V1版本显然满足不了需求
- 升级版本V2
public class TicketWindowV2 implements Runnable {
private final static Integer MAX = 50;
private Integer index = 1;
@Override
public void run() {
while (index <= MAX) {
System.out.println(Thread.currentThread() + " 的号码为:" + index++);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class BackV2 {
public static void main(String[] args) {
final TicketWindowV2 windowV2 = new TicketWindowV2();
Thread t1 = new Thread(windowV2,"窗口1");
Thread t2 = new Thread(windowV2,"窗口2");
Thread t3 = new Thread(windowV2,"窗口3");
t1.start();
t2.start();
t3.start();
}
}
V2运行结果:
Thread[窗口1,5,main] 的号码为:1
Thread[窗口3,5,main] 的号码为:2
Thread[窗口2,5,main] 的号码为:1
Thread[窗口3,5,main] 的号码为:3
Thread[窗口1,5,main] 的号码为:4
Thread[窗口2,5,main] 的号码为:5
Thread[窗口1,5,main] 的号码为:6
Thread[窗口3,5,main] 的号码为:7
Thread[窗口2,5,main] 的号码为:8
Thread[窗口2,5,main] 的号码为:9
Thread[窗口3,5,main] 的号码为:11
Thread[窗口1,5,main] 的号码为:10
Thread[窗口2,5,main] 的号码为:12
Thread[窗口3,5,main] 的号码为:12
Thread[窗口1,5,main] 的号码为:13
Thread[窗口1,5,main] 的号码为:14
Thread[窗口2,5,main] 的号码为:16
Thread[窗口3,5,main] 的号码为:15
Thread[窗口1,5,main] 的号码为:17
Thread[窗口2,5,main] 的号码为:19
Thread[窗口3,5,main] 的号码为:18
Thread[窗口1,5,main] 的号码为:20
Thread[窗口2,5,main] 的号码为:21
Thread[窗口3,5,main] 的号码为:22
Thread[窗口2,5,main] 的号码为:23
Thread[窗口3,5,main] 的号码为:25
Thread[窗口1,5,main] 的号码为:24
Thread[窗口1,5,main] 的号码为:26
Thread[窗口3,5,main] 的号码为:27
Thread[窗口2,5,main] 的号码为:28
Thread[窗口1,5,main] 的号码为:29
Thread[窗口3,5,main] 的号码为:30
Thread[窗口2,5,main] 的号码为:30
Thread[窗口3,5,main] 的号码为:31
Thread[窗口1,5,main] 的号码为:32
Thread[窗口2,5,main] 的号码为:31
Thread[窗口3,5,main] 的号码为:32
Thread[窗口2,5,main] 的号码为:33
Thread[窗口1,5,main] 的号码为:33
Thread[窗口1,5,main] 的号码为:34
Thread[窗口2,5,main] 的号码为:35
Thread[窗口3,5,main] 的号码为:34
Thread[窗口2,5,main] 的号码为:36
Thread[窗口1,5,main] 的号码为:37
Thread[窗口3,5,main] 的号码为:37
Thread[窗口1,5,main] 的号码为:38
Thread[窗口2,5,main] 的号码为:39
Thread[窗口3,5,main] 的号码为:40
Thread[窗口1,5,main] 的号码为:41
Thread[窗口2,5,main] 的号码为:41
Thread[窗口3,5,main] 的号码为:42
Thread[窗口1,5,main] 的号码为:43
Thread[窗口2,5,main] 的号码为:44
Thread[窗口3,5,main] 的号码为:45
Thread[窗口2,5,main] 的号码为:46
Thread[窗口1,5,main] 的号码为:46
Thread[窗口3,5,main] 的号码为:47
Thread[窗口1,5,main] 的号码为:48
Thread[窗口2,5,main] 的号码为:48
Thread[窗口3,5,main] 的号码为:49
Thread[窗口1,5,main] 的号码为:50
Thread[窗口2,5,main] 的号码为:51
可以看到叫的号可能会重复,最后拿到的号也大于50了
例子4-用策略模式实现计算器
@FunctionalInterface
public interface CalculatorStrategy {
double calculator(double salary,double bonus);
}
public class CalculatorStrategyImpl implements CalculatorStrategy {
private final static double SALARY_RATE = 0.1;
private final static double BONUS_RATE = 0.15;
@Override
public double calculator(double salary, double bonus) {
return salary*SALARY_RATE+BONUS_RATE*bonus;
}
}
public class TaxCalculator {
private final double salary;
private final double bonus;
private CalculatorStrategy calculatorStrategy;
public TaxCalculator(double salary, double bonus, CalculatorStrategy calculatorStrategy) {
this.salary = salary;
this.bonus = bonus;
this.calculatorStrategy = calculatorStrategy;
}
public TaxCalculator(double salary, double bonus) {
this.salary = salary;
this.bonus = bonus;
}
public double calculate(){
return this.calcTax();
}
protected double calcTax() {
return calculatorStrategy.calculator(salary,bonus);
}
public void setCalculatorStrategy(CalculatorStrategy calculatorStrategy) {
this.calculatorStrategy = calculatorStrategy;
}
public double getSalary() {
return salary;
}
public double getBonus() {
return bonus;
}
}
public class TaxCalculatorMain {
public static void main(String[] args) {
TaxCalculator taxCalculator = new TaxCalculator(10000d, 2000d);
CalculatorStrategy strategy = new CalculatorStrategyImpl();
taxCalculator.setCalculatorStrategy(strategy);
System.out.println(taxCalculator.calculate());
//采用Java8
TaxCalculator taxCalculator2 = new TaxCalculator(10000d, 2000d, (a, b) -> a * 0.1 + b * 0.15);
System.out.println(taxCalculator2.calculate());
}
}
例子5
// 线程的创建,线程名称自增规则,命名方式
public class CreateThread {
public static void main(String[] args) {
Thread t1 = new Thread();
Thread t2 = new Thread() {
@Override
public void run() {
System.out.println("==========");
}
};
t1.start();
t2.start();
System.out.println(t1.getName());
System.out.println(t2.getName());
Thread t3 = new Thread("MyName");
Thread t4 = new Thread(() -> {
System.out.println("Runnable...");
});
System.out.println(t3.getName());
System.out.println(t4.getName());
Thread t5 = new Thread(() -> {
System.out.println("Runnable..." + Thread.currentThread().getName());
}, "RunnableThread");
t5.start();
}
}
public class CreateThread2 {
public static void main(String[] args) {
Thread t = new Thread() {
public void run() {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
t.start();
System.out.println("==================");
System.out.println(t.getThreadGroup());//java.lang.ThreadGroup[name=main,maxpri=10]
System.out.println(Thread.currentThread().getName());//main
ThreadGroup threadGroup = Thread.currentThread().getThreadGroup();
System.out.println(threadGroup.getName());//main
System.out.println("==================");
System.out.println(threadGroup.activeCount());//3
Thread[] threads = new Thread[threadGroup.activeCount()];
threadGroup.enumerate(threads);
Arrays.asList(threads).forEach(System.out::println);
//Thread[main,5,main]
//Thread[Monitor Ctrl-Break,5,main]
//Thread[Thread-0,5,]
}
}
public class CreateThread3 {
private int i = 0;
private byte[] bytes = new byte[1024];
private static int counter = 0;
//JVM will create a thread named "main"
public static void main(String[] args) {
//create a JVM stack
try {
add(0);
} catch (Error e) {
e.printStackTrace();
System.out.println(counter); //31457
}
}
private static void add(int i) {
++counter;
add(i + 1);
}
}
public class CreateThread4 {
private static int counter = 1;
public static void main(String[] args) {
Thread t1 = new Thread(null, new Runnable() {
@Override
public void run() {
try {
add(1);
} catch (Error e) {
System.out.println(counter);
}
}
private void add(int i) {
counter++;
add(i + 1);
}
}, "Test", 1 << 24);
t1.start();
//260419
}
}
public class CreateThread5 {
private static int counter = 1;
public static void main(String[] args) {
try {
for (int i = 0; i < 1000; i++) {
counter++;
new Thread(new Runnable() {
@Override
public void run() {
try {
add(1);
} catch (Error e) {
// System.out.println(counter);
}
}
private void add(int i) {
add(i + 1);
}
}).start();
}
} catch (Error e) {
counter++;
}
System.out.println("Total created thread nums=>" + counter);
}
}
总结:
1、创建线程对象Thread,默认有一个线程名,以Thread-开头,从0开始计数
2、如果在构造Thread的时候没有传递Runnable或者没有复写Thread的run方法,该Thread将不会调用任何东西,如果传递了Runnable
接口的实例,或者复写了Thread的run方法,则会执行该方法的逻辑单元
3、如果构造线程对象时未传入ThreadGroup,Thread会默认获取父线程的ThreadGroup作为该线程的ThreadGroup,此时
子线程和父线程将会在同一个ThreadGroup中
4、构造Thread的时候传入stackSize代表着该线程占用的stack大小,如果没有指定stacksize的大小,
默认是0,0代表着会忽略该参数,该参数会被JNI函数去使用 。需要注意:该参数有一些平台有效,在有些平台则无效
例子6-守护线程
//守护线程
/**
* A<---------------------------------->B
* ->daemonThread(health check)
* */
public class DaemonThread {
public static void main(String[] args) throws InterruptedException {
Thread t = new Thread() {
@Override
public void run() {
try {
System.out.println(Thread.currentThread().getName() + " running");
Thread.sleep(100000);
System.out.println(Thread.currentThread().getName() + " done.");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}; //new
t.setDaemon(true);
//runnable ->running| ->dead| ->blocked
t.start();
Thread.sleep(5_000); //JDK1.7
System.out.println(Thread.currentThread().getName());
}
}
public class DaemonThread2 {
public static void main(String[] args) {
Thread t = new Thread(() -> {
Thread innerThread = new Thread(() -> {
try {
while (true) {
System.out.println("Do some thing for health check.");
Thread.sleep(1_000);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
});
// innerThread.setDaemon(true); 设置为守护线程,该线程会关闭
innerThread.start();
try {
Thread.sleep(1_000);
System.out.println("T thread finish done.");
} catch (InterruptedException e) {
e.printStackTrace();
}
});
//t.setDaemon(true);
t.start();
}
}
public class ThreadSimpleAPI {
public static void main(String[] args) {
Thread t = new Thread(() -> {
Optional.of("Hello").ifPresent(System.out::println);
try {
Thread.sleep(100_000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}, "t1");
t.start();
Optional.of(t.getName()).ifPresent(System.out::println);
Optional.of(t.getId()).ifPresent(System.out::println);
Optional.of(t.getPriority()).ifPresent(System.out::println);
}
}
//输出
t1
Hello
12
5
//线程优先级(并不是严格按照高中低执行的)
public class ThreadSimpleAPI2 {
public static void main(String[] args) {
Thread t1 = new Thread(() -> {
for (int i = 0; i < 1000; i++) {
Optional.of(Thread.currentThread().getName() + "-Index" + i).ifPresent(System.out::println);
}
});
t1.setPriority(Thread.MAX_PRIORITY);
Thread t2 = new Thread(() -> {
for (int i = 0; i < 1000; i++) {
Optional.of(Thread.currentThread().getName() + "-Index" + i).ifPresent(System.out::println);
}
});
t2.setPriority(Thread.NORM_PRIORITY);
Thread t3 = new Thread(() -> {
for (int i = 0; i < 1000; i++) {
Optional.of(Thread.currentThread().getName() + "-Index" + i).ifPresent(System.out::println);
}
});
t3.setPriority(Thread.MIN_PRIORITY);
t1.start();
t2.start();
t3.start();
}
}
例子7-join()
//join :join的线程全部运行完之后,别的线程才会开始运行
public class ThreadJoin {
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(() -> {
IntStream.range(1, 1000)
.forEach(i -> System.out.println(Thread.currentThread().getName() + "->" + i));
});
Thread t2 = new Thread(() -> {
IntStream.range(1, 1000)
.forEach(i -> System.out.println(Thread.currentThread().getName() + "->" + i));
});
t1.start();
t2.start();
t1.join();
t2.join();
Optional.of("All of tasks finish done.").ifPresent(System.out::println);
IntStream.range(1, 1000)
.forEach(i -> System.out.println(Thread.currentThread().getName() + "->" + i));
}
}
//join(long millis, int nanos)
public class ThreadJoin2 {
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(() -> {
try {
System.out.println("t1 is running");
Thread.sleep(10_000);
System.out.println("t1 is done");
} catch (InterruptedException e) {
e.printStackTrace();
}
});
t1.start();
t1.join(100,10);
Optional.of("All of tasks finish done.").ifPresent(System.out::println);
IntStream.range(1, 1000)
.forEach(i -> System.out.println(Thread.currentThread().getName() + "->" + i));
//start httpServer
// JettyHttpServer.start();
// Thread.currentThread().join();
// Thread t1 = new Thread(() -> {
//
// System.out.println("t1 is running");
// while (true) {
// System.out.println(Thread.currentThread().isInterrupted());
// }
// });
// t1.start();
// Thread t2 = new Thread(() -> {
// try {
// Thread.sleep(10000);
// t1.interrupt();
// System.out.println("interrupt");
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
//
// });
// t2.start();
//
// try {
// t1.join(1000);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
}
}
用join()写的一个例子:三个机器全部运行完成输出打印结果。
public class ThreadJoin3 {
public static void main(String[] args) throws InterruptedException {
long startTimestamp = System.currentTimeMillis();
Thread t1 = new Thread(new CaptureRunnable("M1", 10000L));
Thread t2 = new Thread(new CaptureRunnable("M2", 30000L));
Thread t3 = new Thread(new CaptureRunnable("M3", 15000L));
t1.start();
t2.start();
t3.start();
t1.join();
t2.join();
t3.join();
long endTimestamp = System.currentTimeMillis();
System.out.printf("Save data begin timestamp is:%s, end timestamp is:%s\n", startTimestamp, endTimestamp);
}
}
class CaptureRunnable implements Runnable {
private String machineName;
private long spendTime;
public CaptureRunnable(String machineName, long spendTime) {
this.machineName = machineName;
this.spendTime = spendTime;
}
@Override
public void run() {
//do the really capture data.
try {
Thread.sleep(spendTime);
System.out.printf(machineName + " completed data capture at timestamp [%s] and successfully.\n", System.currentTimeMillis());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public String getResult() {
return machineName + " finish.";
}
}
例子8-interrupt()
public class ThreadService {
private Thread executeThread;
private boolean finished = false;
public void execute(Runnable task){
executeThread = new Thread(() -> {
Thread runner = new Thread(task);
runner.setDaemon(true);
runner.start();
try {
runner.join();
finished = true;
} catch (InterruptedException e) {
e.printStackTrace();
}
});
executeThread.start();
}
public void shutdown(long mills){
long currentTime = System.currentTimeMillis();
while (!finished){
if ((System.currentTimeMillis() - currentTime) >= mills){
System.out.println("任务超时,需要结束它");
executeThread.interrupt();
break;
}
try {
executeThread.sleep(1);
} catch (InterruptedException e) {
System.out.println("执行线程被打断!");
break;
}
}
finished = false;
}
}
//线程强制关闭
public class ThreadCloseForce {
public static void main(String[] args) {
ThreadService service = new ThreadService();
long start = System.currentTimeMillis();
service.execute(()->{
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
service.shutdown(10000);
long end = System.currentTimeMillis();
System.out.println(end-start);
}
}
//优雅的关闭
public class ThreadCloseGraceful {
private static class Worker extends Thread{
private volatile boolean start = true;
@Override
public void run() {
while (start){
//
}
}
public void shutdown(){
this.start = false;
}
}
public static void main(String[] args) {
Worker worker = new Worker();
worker.start();
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
worker.shutdown();
}
}
//优雅的关闭2
public class ThreadCloseGraceful2 {
private static class Worker extends Thread {
@Override
public void run() {
while (true) {
if (Thread.interrupted()) {
break;
}
}
}
}
public static void main(String[] args) {
Worker worker = new Worker();
worker.start();
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
worker.interrupt();
}
}
//interrupt的例子
public class ThreadInterrupt {
private static final Object MONITOR = new Object();
public static void main(String[] args) throws InterruptedException {
/* Thread t = new Thread() {
@Override
public void run() {
while (true) {
synchronized (MONITOR) {
try {
MONITOR.wait(10);
} catch (InterruptedException e) {
e.printStackTrace();
System.out.println(isInterrupted());
}
}
}
}
};
t.start();
Thread.sleep(100);
System.out.println(t.isInterrupted());//false
t.interrupt();
System.out.println(t.isInterrupted());//true
t.stop();*/
// Thread t = new Thread(() -> {
// while (true) {
// synchronized (MONITOR) {
// try {
// MONITOR.wait(10);
// } catch (InterruptedException e) {
// e.printStackTrace();
// System.out.println(Thread.interrupted());
// }
// }
// }
// });
Thread t = new Thread() {
@Override
public void run() {
while (true) {
}
}
};
t.start();
Thread main = Thread.currentThread();
Thread t2 = new Thread() {
@Override
public void run() {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
main.interrupt();
System.out.println("interrupt");
}
};
t2.start();
try {
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
//---------------------------
}
}
例子9
1、//this锁 锁住的是当前类
public class SynchronizedThis {
public static void main(String[] args) {
ThisLock thisLock = new ThisLock();
new Thread(()-> thisLock.m1()).start();
new Thread(()->thisLock.m2()).start();
}
}
class ThisLock{
private final Object LOCK = new Object();
public void m1(){
synchronized (this){
try {
System.out.println(Thread.currentThread().getName()+this.getClass());
Thread.sleep(10_000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void m2(){
synchronized (this){
try {
System.out.println(Thread.currentThread().getName()+this.getClass());
Thread.sleep(10_000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
2、//synchronized 测试类 顺序执行
public class SynchronizedTest {
private final static Object LOCK = new Object();
public static void main(String[] args) {
Runnable runnable = () -> {
synchronized (LOCK) {
try {
Thread.sleep(2_000);
System.out.println(Thread.currentThread());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
Thread t1 = new Thread(runnable);
Thread t2 = new Thread(runnable);
Thread t3 = new Thread(runnable);
t1.start();
t2.start();
t3.start();
}
}
3、BankVersion2
public class BankVersion2 {
public static void main(String[] args) {
final TicketWindowRunnable ticketWindow = new TicketWindowRunnable();
Thread windowThread1 = new Thread(ticketWindow, "一号窗口");
Thread windowThread2 = new Thread(ticketWindow, "二号窗口");
Thread windowThread3 = new Thread(ticketWindow, "三号窗口");
windowThread1.start();
windowThread2.start();
windowThread3.start();
}
}
public class TicketWindowRunnable implements Runnable {
private final static Integer MAX = 500;
private Integer index = 1;
private final Object MONITOR = new Object();
@Override
public void run() {
while (true) {
synchronized (MONITOR) {
if (index > MAX)
break;
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread() + " 的号码为:" + index++);
}
}
}
}
4、BankVersion3
public class BankVersion3 {
public static void main(String[] args) {
final SynchronizedRunnable ticketWindow = new SynchronizedRunnable();
Thread windowThread1 = new Thread(ticketWindow, "一号窗口");
Thread windowThread2 = new Thread(ticketWindow, "二号窗口");
Thread windowThread3 = new Thread(ticketWindow, "三号窗口");
windowThread1.start();
windowThread2.start();
windowThread3.start();
}
}
public class SynchronizedRunnable implements Runnable {
private int index = 1;
//只读共享数据
private final static int MAX = 500;
//this
@Override
public void run() {
while (true) {
if (ticket()) {
break;
}
}
}
// private synchronized boolean ticket() {
// if (index>MAX){
// return true;
// }
// try {
// Thread.sleep(5);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
// System.out.println(Thread.currentThread() + " 的号码是:" + (index++));
// return false;
// }
private boolean ticket() {
synchronized (this) {
if (index > MAX) {
return true;
}
try {
Thread.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread() + " 的号码是:" + (index++));
return false;
}
}
}
5、//静态同步代码块
public class SychronizedStaticTest {
public static void main(String[] args) {
new Thread("T1") {
@Override
public void run() {
SynchronizedStatic.m1();
}
}.start();
new Thread("T2") {
@Override
public void run() {
SynchronizedStatic.m2();
}
}.start();
new Thread("T3") {
@Override
public void run() {
SynchronizedStatic.m3();
}
}.start();
}
}
public class SynchronizedStatic {
static {
synchronized (SynchronizedStatic.class) {
try {
System.out.println("static " + Thread.currentThread().getName());
Thread.sleep(10_000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public synchronized static void m1() {
System.out.println("m1 " + Thread.currentThread().getName());
try {
Thread.sleep(10_000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public synchronized static void m2() {
System.out.println("m2 " + Thread.currentThread().getName());
try {
Thread.sleep(10_000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void m3() {
System.out.println("m3 " + Thread.currentThread().getName());
try {
Thread.sleep(10_000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
/**
输出
static T1
m1 T1
m3 T3
m2 T2
**/
例子10-deadLock
/**
死锁例子
查看方式:jps
jstack 端口
*/
public class DeadLockExample {
public static void main(String[] args) {
deadLock();
}
private static void deadLock() {
final Object OBJ1 = new Object();
final Object OBJ2 = new Object();
new Thread(() -> {
synchronized (OBJ1) {
System.out.println("获取obj1成功");
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (OBJ2) {
System.out.println("获取obj2成功");
}
}
}).start();
new Thread(() -> {
synchronized (OBJ2) {
System.out.println("获取obj2成功");
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (OBJ1) {
System.out.println("获取obj1成功");
}
}
}).start();
}
}
//自定义deadLock
public class OtherService {
private final Object lock = new Object();
private DeadLock deadLock;
public void s1() {
synchronized (lock){
System.out.println("s1========");
}
}
public void s2(){
synchronized (lock){
System.out.println("s2====");
deadLock.m2();
}
}
public void setDeadLock(DeadLock deadLock) {
this.deadLock = deadLock;
}
}
public class DeadLock {
private OtherService otherService;
public DeadLock(OtherService otherService) {
this.otherService = otherService;
}
private final Object lock = new Object();
public void m1() {
synchronized (lock) {
System.out.println("m1");
otherService.s1();
}
}
public void m2() {
synchronized (lock) {
System.out.println("m2");
}
}
}
public class DeadLockTest {
public static void main(String[] args) {
OtherService otherService = new OtherService();
DeadLock deadLock = new DeadLock(otherService);
otherService.setDeadLock(deadLock);
new Thread(() -> {
while (true) {
deadLock.m1();
}
}).start();
new Thread(() -> {
while (true)
otherService.s2();
}).start();
}
}
例子11
/**
* 采集sevice
* 同时工作的线程不超过5个
*/
public class CaptureService {
private final static LinkedList<Control> CONTROLS = new LinkedList();
private final static Integer MAX_WORKER = 5;
public static void main(String[] args) {
List<Thread> worker = new ArrayList<>();
Arrays.asList("M1", "M2", "M3", "M4", "M5", "M6", "M7", "M8", "M9", "M10").stream()
.map(CaptureService::createCaptureThread).forEach(
t->{
t.start();
worker.add(t);
}
);
worker.stream().forEach(
t->{
try {
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
);
Optional.of("All of capture work finished").ifPresent(System.out::println);
}
private static Thread createCaptureThread(String name) {
return new Thread(()->{
Optional.of("The worker [" + Thread.currentThread().getName() + "] BEGIN capture data.")
.ifPresent(System.out::println);
synchronized (CONTROLS){
while (CONTROLS.size()>MAX_WORKER){
try {
CONTROLS.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
CONTROLS.addLast(new Control());;
}
Optional.of("The worker [" + Thread.currentThread().getName() + "] is working...")
.ifPresent(System.out::println);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (CONTROLS){
Optional.of("The worker [" + Thread.currentThread().getName() + "] END capture data.")
.ifPresent(System.out::println);
CONTROLS.removeFirst();
CONTROLS.notifyAll();
}
},name);
}
}
class Control{
}
wait和sleep的不同
public class DifferenceOfWaitAndSleep {
private final static Object LOCK = new Object();
public static void main(String[] args) {
Stream.of("T1", "T2").forEach(name ->
new Thread(name) {
@Override
public void run() {
m2();
}
}.start()
);
}
public static void m1() {
synchronized (LOCK) {
try {
System.out.println("The Thread " + Thread.currentThread().getName() + " enter.");
Thread.sleep(20000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void m2() {
synchronized (LOCK) {
try {
System.out.println("The Thread " + Thread.currentThread().getName() + " enter.");
LOCK.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
生产者消费者问题1(生产完没告诉我,也不知道是不是最新的)
public class ProduceConsumerVersion1 {
private int i = 1;
final private Object LOCK = new Object();
private void produce() {
synchronized (LOCK) {
System.out.println("P->" + (i++));
}
}
private void consume() {
synchronized (LOCK) {
System.out.println("C->" + i);
}
}
public static void main(String[] args) {
ProduceConsumerVersion1 pc = new ProduceConsumerVersion1();
new Thread("P") {
@Override
public void run() {
while (true)
pc.produce();
}
}.start();
new Thread("C") {
@Override
public void run() {
while (true)
pc.consume();
}
}.start();
}
}
生产者消费者2(多线程下有问题)假死:都放弃了CP执行权 wait了
public class ProduceConsumerVersion2 {
private int i = 0;
private final Object LOCK = new Object();
private volatile boolean isProduce = false;
public void produce() {
synchronized (LOCK){
if (isProduce){
try {
LOCK.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}else{
i++;
System.out.println("P->"+i);
LOCK.notify();
isProduce = true;
}
}
}
public void consume(){
synchronized (LOCK){
if (isProduce){
System.out.println("C->"+i);
LOCK.notify();
isProduce = false;
}else{
try {
LOCK.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) {
ProduceConsumerVersion2 pc = new ProduceConsumerVersion2();
Stream.of("P1","P2").forEach(
n-> new Thread(n){
@Override
public void run() {
while (true)
pc.produce();
}
}.start()
);
Stream.of("C1","C2").forEach(
n-> new Thread(n){
@Override
public void run() {
while (true)
pc.consume();
}
}.start()
);
}
}
生产者消费者3 (多线程完整版)
//
public class ProduceConsumerVersion3 {
private int i = 0;
private final Object LOCK = new Object();
private volatile boolean isProduce = false;
public void produce() {
synchronized (LOCK) {
while (isProduce) {
try {
LOCK.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
i++;
System.out.println("P->" + i);
LOCK.notifyAll();
isProduce = true;
}
}
public void consume() {
synchronized (LOCK) {
while (!isProduce) {
try {
LOCK.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("C->" + i);
LOCK.notify();
isProduce = false;
}
}
public static void main(String[] args) {
ProduceConsumerVersion3 pc = new ProduceConsumerVersion3();
Stream.of("P1", "P2").forEach(
n -> new Thread(n) {
@Override
public void run() {
while (true) {
pc.produce();
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start()
);
Stream.of("C1", "C2").forEach(
n -> new Thread(n) {
@Override
public void run() {
while (true){
pc.consume();
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start()
);
}
}
sleep()和wait()的区别:
1.sleep()是Thread()的方法,而wait()是Object()的方法
2.sleep()不会释放Object的监控,而wait()会释放监控并把Object monitor加到队列中
3.sleep()不依赖monitor,而wait()需要
4.sleep()不需要wakeup,而wait()需要
例子12-自定义lock锁
public interface Lock {
class TimeOutException extends Exception {
public TimeOutException(String message) {
super(message);
}
}
void lock() throws InterruptedException;
void lock(long mills) throws InterruptedException, TimeOutException;
void unlock();
Collection<Thread> getBlockedThread();
int getBlockedSize();
}
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Optional;
public class BooleanLock implements Lock {
private boolean initValue;
private Collection<Thread> blockedThreadCollection = new ArrayList<>();
private Thread currentThread;
public BooleanLock() {
this.initValue = false;
}
@Override
public synchronized void lock() throws InterruptedException {
while (initValue){
blockedThreadCollection.add(Thread.currentThread());
this.wait();
}
blockedThreadCollection.remove(Thread.currentThread());
this.initValue = true;
this.currentThread = Thread.currentThread();
}
@Override
public synchronized void lock(long mills) throws InterruptedException, TimeOutException {
if (mills <=0){
lock();
}
long hasRemaining = mills;
long endTime = System.currentTimeMillis() + mills;
while (initValue){
if (hasRemaining<=0){
throw new TimeOutException("Time Out");
}
blockedThreadCollection.add(Thread.currentThread());
this.wait(mills);
hasRemaining= endTime - System.currentTimeMillis();
}
this.initValue = true;
this.currentThread = Thread.currentThread();
}
@Override
public synchronized void unlock() {
if (Thread.currentThread() == currentThread){
this.initValue = false;
Optional.of(Thread.currentThread().getName() + " release the lock monitor.")
.ifPresent(System.out::println);
this.notifyAll();
}
}
@Override
public Collection<Thread> getBlockedThread() {
return Collections.unmodifiableCollection(blockedThreadCollection);
}
@Override
public int getBlockedSize() {
return blockedThreadCollection.size();
}
}
import java.util.Optional;
import java.util.stream.Stream;
public class LockTest {
public static void main(String[] args) throws InterruptedException {
final BooleanLock booleanLock = new BooleanLock();
Stream.of("T1", "T2", "T3", "T4")
.forEach(name ->
new Thread(() -> {
try {
booleanLock.lock(100L);
Optional.of(Thread.currentThread().getName() + " have the lock Monitor")
.ifPresent(System.out::println);
work();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (Lock.TimeOutException e) {
Optional.of(Thread.currentThread().getName() + " time out")
.ifPresent(System.out::println);
} finally {
booleanLock.unlock();
}
}, name).start()
);
}
private static void work() throws InterruptedException {
Optional.of(Thread.currentThread().getName() + " is Working...")
.ifPresent(System.out::println);
Thread.sleep(4_000);
}
}
例子13 -线程发生异常怎么捕获
//Thread对发生异常的捕获
public class ThreadException {
private final static int A = 10;
private final static int B = 0;
public static void main(String[] args) {
// new Test1().test();
Thread t = new Thread(() -> {
try {
Thread.sleep(5_000L);
int result = A / B;
System.out.println(result);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
t.setUncaughtExceptionHandler((thread, e) -> {
System.out.println(e);
System.out.println(thread);
});
t.start();
}
}
public class Test1
{
private Test2 test2 = new Test2();
public void test(){
test2.test();
}
}
public class Test2 {
public void test() {
Arrays.asList(Thread.currentThread().getStackTrace()).stream()
.filter(e->!e.isNativeMethod())
.forEach(e-> Optional.of(e.getClassName()+":"+e.getMethodName()+":"+e.getLineNumber())
.ifPresent(System.out::println));
}
}
例子14-ThreadGroup
创建ThreadGroup
public class ThreadGroupCreate {
public static void main(String[] args) {
//use the name
ThreadGroup tg1 = new ThreadGroup("TG1");
Thread t1 = new Thread(tg1, "t1") {
@Override
public void run() {
while (true) {
try {
System.out.println(getThreadGroup().getName());//TG1
System.out.println(getThreadGroup().getParent());//java.lang.ThreadGroup[name=main,maxpri=10]
System.out.println(getThreadGroup().getParent().activeCount());//3
Thread.sleep(0);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
t1.start();
System.out.println("===============");
ThreadGroup tg2 = new ThreadGroup("TG2");
Thread t2 = new Thread(tg2, "T2") {
@Override
public void run() {
System.out.println(">>>"+tg1.getName());//>>>TG1
Thread[] threads = new Thread[tg1.activeCount()];
tg1.enumerate(threads);
System.out.println("+++");
Arrays.asList(threads).forEach(System.out::println);//Thread[t1,5,TG1]
}
};
t2.start();
System.out.println(tg2.getName());//TG2
System.out.println(tg2.getParent());//java.lang.ThreadGroup[name=main,maxpri=10]
System.out.println(Thread.currentThread().getName());//main
System.out.println(Thread.currentThread().getThreadGroup().getName());//main
}
}
ThreadAPI
public class ThreadGroupAPI {
public static void main(String[] args) throws InterruptedException {
ThreadGroup tg1 = new ThreadGroup("TG1");
Thread t1 = new Thread(tg1, "t1") {
@Override
public void run() {
while (true) {
try {
Thread.sleep(1_000);
} catch (InterruptedException e) {
e.printStackTrace();
break;
}
}
}
};
// tg1.setDaemon(true);
t1.start();
// Thread.sleep(2_000);
// System.out.println(tg1.isDestroyed());
// tg1.destroy();
// System.out.println(tg1.isDestroyed());
//
ThreadGroup tg2 = new ThreadGroup(tg1, "TG2");
Thread t2 = new Thread(tg2, "T2") {
@Override
public void run() {
while (true) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
break;
}
}
}
};
t2.start();
System.out.println(tg1.activeCount());
System.out.println(tg1.activeGroupCount());
t2.checkAccess();
// tg1.destroy();
System.out.println("=========================");
Thread[] ts1 = new Thread[tg1.activeCount()];
tg1.enumerate(ts1);
Arrays.asList(ts1).forEach(System.out::println);
System.out.println("=========================");
tg1.enumerate(ts1, true);
Arrays.asList(ts1).forEach(System.out::println);
System.out.println("=========================");
ts1 = new Thread[10];
Thread.currentThread().getThreadGroup().enumerate(ts1, false);
Arrays.asList(ts1).forEach(System.out::println);
tg1.interrupt();
}
}
简单的线程池
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
public class SimpleThreadPool extends Thread {
private int size;
private final int queueSize;
private final static int DEFAULT_TASK_QUEUE_SIZE = 2000;
private static volatile int seq = 0;
private final static String THREAD_PREFIX = "SIMPLE_THREAD_POOL-";
private final static ThreadGroup GROUP = new ThreadGroup("Pool_Group");
private final static LinkedList<Runnable> TASK_QUEUE = new LinkedList<>();
private final static List<WorkerTask> THREAD_QUEUE = new ArrayList<>();
private final DiscardPolicy discardPolicy;
public final static DiscardPolicy DEFAULT_DISCARD_POLICY = () -> {
throw new DiscardException("Discard This Task.");
};
private volatile boolean destroy = false;
private int min;
private int max;
private int active;
public SimpleThreadPool() {
this(4, 8, 12, DEFAULT_TASK_QUEUE_SIZE, DEFAULT_DISCARD_POLICY);
}
public SimpleThreadPool(int min, int active, int max, int queueSize, DiscardPolicy discardPolicy) {
this.min = min;
this.active = active;
this.max = max;
this.queueSize = queueSize;
this.discardPolicy = discardPolicy;
init();
}
private void init() {
for (int i = 0; i < this.min; i++) {
createWorkTask();
}
this.size = min;
this.start();
}
public void submit(Runnable runnable) {
if (destroy)
throw new IllegalStateException("The thread pool already destroy and not allow submit task.");
synchronized (TASK_QUEUE) {
if (TASK_QUEUE.size() > queueSize)
discardPolicy.discard();
TASK_QUEUE.addLast(runnable);
TASK_QUEUE.notifyAll();
}
}
@Override
public void run() {
while (!destroy) {
System.out.printf("Pool#Min:%d,Active:%d,Max:%d,Current:%d,QueueSize:%d\n",
this.min, this.active, this.max, this.size, TASK_QUEUE.size());
try {
Thread.sleep(5_000L);
if (TASK_QUEUE.size() > active && size < active) {
for (int i = size; i < active; i++) {
createWorkTask();
}
System.out.println("The pool incremented to active.");
size = active;
} else if (TASK_QUEUE.size() > max && size < max) {
for (int i = size; i < max; i++) {
createWorkTask();
}
System.out.println("The pool incremented to max.");
size = max;
}
synchronized (THREAD_QUEUE) {
if (TASK_QUEUE.isEmpty() && size > active) {
System.out.println("=========Reduce========");
int releaseSize = size - active;
for (Iterator<WorkerTask> it = THREAD_QUEUE.iterator(); it.hasNext(); ) {
if (releaseSize <= 0)
break;
WorkerTask task = it.next();
task.close();
task.interrupt();
it.remove();
releaseSize--;
}
size = active;
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
private void createWorkTask() {
WorkerTask task = new WorkerTask(GROUP, THREAD_PREFIX + (seq++));
task.start();
THREAD_QUEUE.add(task);
}
public void shutdown() throws InterruptedException {
while (!TASK_QUEUE.isEmpty()) {
Thread.sleep(50);
}
synchronized (THREAD_QUEUE) {
int initVal = THREAD_QUEUE.size();
while (initVal > 0) {
for (WorkerTask task : THREAD_QUEUE) {
if (task.getTaskState() == TaskState.BLOCKED) {
task.interrupt();
task.close();
initVal--;
} else {
Thread.sleep(10);
}
}
}
}
System.out.println(GROUP.activeCount());
this.destroy = true;
System.out.println("The thread pool disposed.");
}
public int getQueueSize() {
return queueSize;
}
public int getSize() {
return size;
}
public boolean isDestroy() {
return this.destroy;
}
public int getMin() {
return min;
}
public int getMax() {
return max;
}
public int getActive() {
return active;
}
private enum TaskState {
FREE, RUNNING, BLOCKED, DEAD
}
public static class DiscardException extends RuntimeException {
public DiscardException(String message) {
super(message);
}
}
public interface DiscardPolicy {
void discard() throws DiscardException;
}
private static class WorkerTask extends Thread {
private volatile TaskState taskState = TaskState.FREE;
public WorkerTask(ThreadGroup group, String name) {
super(group, name);
}
public TaskState getTaskState() {
return this.taskState;
}
public void run() {
OUTER:
while (this.taskState != TaskState.DEAD) {
Runnable runnable;
synchronized (TASK_QUEUE) {
while (TASK_QUEUE.isEmpty()) {
try {
taskState = TaskState.BLOCKED;
TASK_QUEUE.wait();
} catch (InterruptedException e) {
System.out.println("Closed.");
break OUTER;
}
}
runnable = TASK_QUEUE.removeFirst();
}
if (runnable != null) {
taskState = TaskState.RUNNING;
runnable.run();
taskState = TaskState.FREE;
}
}
}
public void close() {
this.taskState = TaskState.DEAD;
}
}
public static void main(String[] args) throws InterruptedException {
SimpleThreadPool threadPool = new SimpleThreadPool();
for (int i = 0; i < 40; i++) {
threadPool.submit(() -> {
System.out.println("The runnable be serviced by " + Thread.currentThread() + " start.");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("The runnable be serviced by " + Thread.currentThread() + " finished.");
});
}
Thread.sleep(10000);
threadPool.shutdown();
/* Thread.sleep(10000);
threadPool.shutdown();
threadPool.submit(() -> System.out.println("======="));*/
}
}