Skip to content

Commit

Permalink
add six demo to project
Browse files Browse the repository at this point in the history
  • Loading branch information
ZacharyHua committed May 23, 2019
1 parent 286ceae commit 61f7521
Show file tree
Hide file tree
Showing 7 changed files with 418 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.study.basejava.a1_thread_status;

/**
* 示例1 - JAVA程序执行分析
*/
public class Demo1 {
public int x;
public int sum (int a, int b){
return a + b ;
}

public static void main(String[] args) {
Demo1 demo1 = new Demo1();
demo1.x = 3;
int y = 3;
int z = demo1.sum(demo1.x,y);
System.out.println("person age is " + z);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package com.study.basejava.a1_thread_status;

/**
* 示例2 - 多线程运行状态切换示例
*/
public class Demo2 {
public static Thread thread1;
public static Demo2 obj;

public static void main(String[] args) throws InterruptedException {
// 第一种状态切换 - 新建 -> 运行 -> 终止
threadRunTimeStatus1();
System.out.println();
System.out.println("-----------------");
System.out.println();
// 第二种状态切换 - 新建 -> 运行 -> 等待 -> 运行 -> 终止(sleep方式)
threadRunTimeStatus2();
System.out.println();
System.out.println("-----------------");
System.out.println();
// 第三种状态切换 - 新建 -> 运行 -> 阻塞 -> 运行 -> 终止
threadRunTimeStatus3();
}

public static void threadRunTimeStatus1() throws InterruptedException {
System.out.println("#######第一种状态切换 -> 新建 -> 运行 -> 终止################################");
Thread thread1 = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("thread1当前状态:"+Thread.currentThread().getState().toString());
System.out.println("thread1执行了");
}
});
System.out.println("没调用start方法,thread1当前状态:"+thread1.getState().toString());
thread1.start();
Thread.sleep(2000L); // 等待thread1执行完成后,再看线程状态
System.out.println("等待thread1执行完成后,再看线程状态:"+thread1.getState().toString());
// thread1.start(); TODO 注意,线程终止之后,再进行调用,会抛出IllegalThreadStateException异常
}

public static void threadRunTimeStatus2() throws InterruptedException {
System.out.println("############第二种:新建 -> 运行 -> 等待 -> 运行 -> 终止(sleep方式)###########################");
Thread thread2 = new Thread(new Runnable() {
@Override
public void run() {
try { // 将线程thread2置位等待状态 1500毫秒后唤醒
Thread.sleep(1500L);
}catch (InterruptedException e){
e.printStackTrace();
}finally {
System.out.println("thread2当前状态:"+Thread.currentThread().getState().toString());
System.out.println("thread2执行了");
}
}
});
System.out.println("没调用start方法,thread2当前状态:"+thread2.getState().toString());
thread2.start();
Thread.sleep(200L); // 等待 200ms 再看thread2的状态
System.out.println("等待200毫秒,再看thread2当前状态:"+thread2.getState().toString());
Thread.sleep(3000L); // 等待 3000ms 再看thread2的状态
System.out.println("等待3秒,再看thread2当前状态:" + thread2.getState().toString());
}

public static void threadRunTimeStatus3() throws InterruptedException {
System.out.println("############第三种:新建 -> 运行 -> 阻塞 -> 运行 -> 终止###########################");
Thread thread3 = new Thread(new Runnable() {
@Override
public void run() {
synchronized (Demo2.class) {
System.out.println("thread3当前状态:" + Thread.currentThread().getState().toString());
System.out.println("thread3 执行了");
}
}
});
synchronized (Demo2.class){
System.out.println("没调用start方法,thread2当前状态:"+thread3.getState().toString());
thread3.start();
System.out.println("调用start方法,thread3当前状态:" + thread3.getState().toString());
Thread.sleep(200L); // 等待 200ms 再看thread3的状态
System.out.println("等待200ms,thread3当前状态:" + thread3.getState().toString());
}
Thread.sleep(3000L); // 等待 3000ms 再看thread3的状态
System.out.println("等待3秒,让thread3抢到锁,再看thread3当前状态:" + thread3.getState().toString());
}


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.study.basejava.a1_thread_status;

/**
* 示例3 - 线程stop强制性中止,破坏线程安全的示例
*/
public class Demo3 {
public static void main(String[] args) throws InterruptedException {
StopThread thread = new StopThread();
thread.start();
// 睡眠1s 确保变量自增成功
Thread.sleep(1000L);
// 暂停线程
thread.stop(); // 错误的终止
// thread.interrupt();
while (thread.isAlive()){
System.out.println("线程的状态"+thread.getState().toString());
// 确保线程已经终止
}
// 输出结果
thread.print();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package com.study.basejava.a1_thread_status;

/**
* 通过状态位来判断
*/
public class Demo4 {
public volatile static boolean flag = true;

public static void main(String[] args) throws InterruptedException {
new Thread(()->{
try {
while (flag){ // 判断是否运行
System.out.println("运行中"+Thread.currentThread().getState().toString());
Thread.sleep(1000L);
}
}catch (InterruptedException e){
e.printStackTrace();
}
}).start();
// 3秒之后,将状态标志改为False,代表不继续运行
Thread.sleep(3000L);
flag = false;
System.out.println("程序运行结束"+Thread.currentThread().getState().toString());
}
}
199 changes: 199 additions & 0 deletions basejava/src/main/java/com/study/basejava/a1_thread_status/Demo5.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,199 @@
package com.study.basejava.a1_thread_status;

import java.util.concurrent.locks.LockSupport;

/**
* 三种线程协作通信的方式:suspend/resume、wait/notify、park/unpark
*/
public class Demo5 {
// 包子店
public static Object baozidian = null ;

/**
* 正常的 suspend/resume
*/
public void suspendResumeTest() throws InterruptedException {
// 启动线程
Thread consumerThread = new Thread(()->{
if (baozidian == null){ // 如果没有包子,则进入等待状态
System.out.println("1. 进入等待状态");
Thread.currentThread().suspend();
}
System.out.println("2. 买到包子,回家");
});
consumerThread.start();
// 等待3秒 生产一个包子
Thread.sleep(3000L);
baozidian = new Object();
consumerThread.resume();
System.out.println("3. 通知消费者去消费");
}

/**
* 死锁的suspend/resume。 suspend并不会像wait一样释放锁,故此容易写出死锁代码
*/
public void suspendResumeDeadLockTest() throws InterruptedException {
// 启动线程
Thread consumeThread = new Thread(() -> {
if (baozidian == null) {
System.out.println("1. 进入等待状态");
synchronized (this) { // 线程被挂起... 没人能够再次拿到锁 故进入死锁状态
Thread.currentThread().suspend();
}
}
System.out.println("2. 买到包子,回家");
});
consumeThread.start();
// 等待3秒 生产一个包子
Thread.sleep(3000L);
baozidian = new Object();
// 争取到锁以后,再恢复consumerThread
synchronized (this) {
consumeThread.resume();
}
System.out.println("3、通知消费者");
}
/**
* 导致程序永久挂起的suspend/resume
*/
public void suspendResumeDeadLockTest2() throws InterruptedException {
// 启动线程
Thread consumerThread = new Thread(() -> {
if (baozidian == null) {
System.out.println("1、没包子,进入等待");
try { // 为这个线程加上一点延时
Thread.sleep(5000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 这里的挂起执行在resume后面
Thread.currentThread().suspend();
}
System.out.println("2、买到包子,回家");
});
consumerThread.start();
// 3秒之后,生产一个包子
Thread.sleep(3000L);
baozidian = new Object();
consumerThread.resume();
System.out.println("3、通知消费者");
consumerThread.join();
}
/**
* 正常的wait、notify
* @throws InterruptedException
*/
public void waitNotifyTest() throws InterruptedException {
new Thread(()->{
synchronized (this){
if (baozidian == null ){
System.out.println("1. 进入等待状态");
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
System.out.println("2. 买到包子,回家");
}).start();
// 3秒之后,生产一个包子
Thread.sleep(3000L);
baozidian = new Object();
synchronized (this){
this.notify();
// this.notifyAll();
System.out.println("3、通知消费者");
}
}

/**
* 会导致程序永久等待的wait/notify
*/
public void waitNotifyDeadLockTest() throws InterruptedException {
new Thread(()->{
if (baozidian == null ){
try {
Thread.sleep(5000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (this){
System.out.println("1、进入等待");
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
System.out.println("2、买到包子,回家");
}).start();
// 3秒之后,生产一个包子
Thread.sleep(3000L);
baozidian = new Object();
synchronized (this){
this.notify();
// this.notifyAll();
System.out.println("3、通知消费者");
}
}

/**
* 正常的park/unpark
* @throws InterruptedException
*/
public void parkUnparkTest() throws InterruptedException {
Thread consumerThread = new Thread(()->{
while (baozidian == null){
System.out.println("1、进入等待");
LockSupport.park();
}
System.out.println("2、买到包子,回家");
});
consumerThread.start();
Thread.sleep(3000L);
baozidian = new Object();
LockSupport.unpark(consumerThread);
System.out.println("3、通知消费者");
}

/**
* 死锁的park/unpark
*/
public void parkUnparkDeadLockTest() throws InterruptedException {
Thread consumerThread = new Thread(()->{
if (baozidian == null){
System.out.println("1、进入等待");
// 当前线程拿到锁,然后挂起
synchronized (this){
LockSupport.park();
}
}
});
consumerThread.start();
Thread.sleep(3000L);
baozidian = new Object();
synchronized (this){
LockSupport.unpark(consumerThread);
}
System.out.println("3、通知消费者");
}

public static void main(String[] args) throws InterruptedException {
Demo5 demo5 = new Demo5();
// 对调用顺序有要求,也要开发自己注意锁的释放。这个被弃用的API, 容易死锁,也容易导致永久挂起。
// demo5.suspendResumeTest();
// demo5.suspendResumeDeadLockTest();
// demo5.suspendResumeDeadLockTest2();

// wait/notify要求再同步关键字里面使用,免去了死锁的困扰,但是一定要先调用wait,再调用notify,否则永久等待了
// demo5.waitNotifyTest();
// demo5.waitNotifyDeadLockTest();

// park/unpark没有顺序要求,但是park并不会释放锁,所有再同步代码中使用要注意
// demo5.parkUnparkTest();
demo5.parkUnparkDeadLockTest();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package com.study.basejava.a1_thread_status;

/**
* 线程封闭
*/
public class Demo6 {
/**
* threadLocal变量,每个线程都有一个副本,互不干扰
*/
public static ThreadLocal<String> value = new ThreadLocal<>();

/**
* threadLocal测试
*/
public void threadLocalTest() throws InterruptedException {
// threadlocal线程封闭示例
value.set("这是主线程设置的123");
String v = value.get();
System.out.println("线程1执行之前,主线程取到的值:" + v);
new Thread(new Runnable() {
@Override
public void run() {
String v = value.get();
System.out.println("线程1取到的值:" + v);
value.set("这是线程1设置的456");
v = value.get();
System.out.println("重新设置之后,线程1取到的值:" + v);
System.out.println("线程1执行结束");
}
}).start();
Thread.sleep(5000L);
v = value.get();
System.out.println("线程1执行之后,主线程取到的值:" + v);
}

public static void main(String[] args) throws InterruptedException {
new Demo6().threadLocalTest();
}
}
Loading

0 comments on commit 61f7521

Please sign in to comment.