-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
a64fc83
commit f11a63f
Showing
6 changed files
with
286 additions
and
0 deletions.
There are no files selected for viewing
79 changes: 79 additions & 0 deletions
79
src/main/java/xyz/xuminghai/atomic/AtomicIntegerArrayDemo.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
package xyz.xuminghai.atomic; | ||
|
||
import java.util.concurrent.atomic.AtomicIntegerArray; | ||
|
||
/** | ||
* 2023/3/13 17:30 星期一<br/> | ||
* | ||
* <h1>AtomicIntegerArray示例</h1> | ||
* 可以看做是一组AtomicInteger | ||
* | ||
* @author xuMingHai | ||
*/ | ||
public class AtomicIntegerArrayDemo { | ||
|
||
private static final AtomicIntegerArray ATOMIC_INTEGER_ARRAY = new AtomicIntegerArray(3); | ||
|
||
public static void main(String[] args) { | ||
Thread t1 = new Thread(() -> { | ||
for (int i = 0; i < 300; i++) { | ||
if ((i % 2) == 0) { | ||
ATOMIC_INTEGER_ARRAY.getAndIncrement(1); | ||
} | ||
else if ((i % 3) == 0) { | ||
ATOMIC_INTEGER_ARRAY.getAndIncrement(2); | ||
} | ||
else { | ||
ATOMIC_INTEGER_ARRAY.getAndIncrement(0); | ||
} | ||
} | ||
|
||
}, "t1"); | ||
|
||
Thread t2 = new Thread(() -> { | ||
for (int i = 0; i < 200; i++) { | ||
if ((i % 2) == 0) { | ||
ATOMIC_INTEGER_ARRAY.getAndDecrement(1); | ||
} | ||
else if ((i % 3) == 0) { | ||
ATOMIC_INTEGER_ARRAY.getAndDecrement(2); | ||
} | ||
else { | ||
ATOMIC_INTEGER_ARRAY.getAndDecrement(0); | ||
} | ||
} | ||
|
||
}, "t2"); | ||
|
||
Thread t3 = new Thread(() -> { | ||
for (int i = 0; i < 100; i++) { | ||
if ((i % 2) == 0) { | ||
ATOMIC_INTEGER_ARRAY.getAndDecrement(1); | ||
} | ||
else if ((i % 3) == 0) { | ||
ATOMIC_INTEGER_ARRAY.getAndDecrement(2); | ||
} | ||
else { | ||
ATOMIC_INTEGER_ARRAY.getAndDecrement(0); | ||
} | ||
} | ||
|
||
}, "t3"); | ||
|
||
t1.start(); | ||
t2.start(); | ||
t3.start(); | ||
|
||
try { | ||
t1.join(); | ||
t2.join(); | ||
t3.join(); | ||
} | ||
catch (InterruptedException e) { | ||
throw new RuntimeException(e); | ||
} | ||
|
||
System.out.println(ATOMIC_INTEGER_ARRAY); | ||
} | ||
|
||
} |
56 changes: 56 additions & 0 deletions
56
src/main/java/xyz/xuminghai/atomic/AtomicIntegerFieldUpdateDemo.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
package xyz.xuminghai.atomic; | ||
|
||
import java.util.StringJoiner; | ||
import java.util.concurrent.atomic.AtomicIntegerFieldUpdater; | ||
|
||
/** | ||
* 2023/3/14 14:07 星期二<br/> | ||
* | ||
* <h1>AtomicIntegerFieldUpdater示例</h1> | ||
* 根据 Java 语言访问控制,调用者无法访问该字段,则出现基于反射的嵌套异常 | ||
* | ||
* @author xuMingHai | ||
*/ | ||
public class AtomicIntegerFieldUpdateDemo { | ||
|
||
public static void main(String[] args) { | ||
|
||
final AtomicIntegerFieldUpdater<VolatileInteger> fieldUpdater = AtomicIntegerFieldUpdater | ||
.newUpdater(VolatileInteger.class, "i"); | ||
final VolatileInteger volatileInteger = new VolatileInteger(); | ||
|
||
Thread t1 = new Thread(() -> fieldUpdater.getAndIncrement(volatileInteger), "t1"); | ||
|
||
Thread t2 = new Thread(() -> fieldUpdater.getAndDecrement(volatileInteger), "t2"); | ||
|
||
Thread t3 = new Thread(() -> fieldUpdater.getAndIncrement(volatileInteger), "t3"); | ||
|
||
t1.start(); | ||
t2.start(); | ||
t3.start(); | ||
|
||
try { | ||
t1.join(); | ||
t2.join(); | ||
t3.join(); | ||
} | ||
catch (InterruptedException e) { | ||
throw new RuntimeException(e); | ||
} | ||
|
||
System.out.println(volatileInteger); | ||
|
||
} | ||
|
||
} | ||
|
||
class VolatileInteger { | ||
volatile int i; | ||
|
||
@Override | ||
public String toString() { | ||
return new StringJoiner(", ", VolatileInteger.class.getSimpleName() + "[", "]") | ||
.add("i=" + i) | ||
.toString(); | ||
} | ||
} |
36 changes: 36 additions & 0 deletions
36
src/main/java/xyz/xuminghai/base/InheritableThreadLocalDemo.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
package xyz.xuminghai.base; | ||
|
||
/** | ||
* 2023/3/15 23:51 星期三<br/> | ||
* | ||
* <h1>可继承的本地变量</h1> | ||
* 适用于父线程创建子线程(由父线程创建的线程)时传递线程局部变量 | ||
* <p color = "red">注意子线程只是创建时局部变量来自父线程,也是完全独立的副本,不会跟随父线程的局部变量变化而变化</p> | ||
* | ||
* @author xuMingHai | ||
*/ | ||
public class InheritableThreadLocalDemo { | ||
|
||
private static final ThreadLocal<String> THREAD_LOCAL = new InheritableThreadLocal<String>() { | ||
@Override | ||
protected String initialValue() { | ||
return "张三"; | ||
} | ||
}; | ||
|
||
public static void main(String[] args) throws InterruptedException { | ||
|
||
Thread t1 = new Thread(() -> System.out.println(Thread.currentThread().getName() + ":THREAD_LOCAL = " + THREAD_LOCAL.get()), "t1"); | ||
t1.start(); | ||
t1.join(); | ||
|
||
System.out.println(Thread.currentThread().getName() + ":THREAD_LOCAL = " + THREAD_LOCAL.get()); | ||
|
||
THREAD_LOCAL.set("李四"); | ||
Thread t2 = new Thread(() -> System.out.println(Thread.currentThread().getName() + ":THREAD_LOCAL = " + THREAD_LOCAL.get()), "t2"); | ||
t2.start(); | ||
System.out.println(Thread.currentThread().getName() + ":THREAD_LOCAL = " + THREAD_LOCAL.get()); | ||
|
||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
package xyz.xuminghai.base; | ||
|
||
/** | ||
* 2023/3/15 23:34 星期三<br/> | ||
* | ||
* <h1>线程局部变量示例</h1> | ||
* 每个线程都存在这个变量的副本,每个线程都只使用自己的ThreadLocalMap维护变量,key为ThreadLocal,value为变量 | ||
* | ||
* @author xuMingHai | ||
*/ | ||
public class ThreadLocalDemo { | ||
|
||
/** | ||
* 使用类变量,可以避免不必要的弱引用清除key | ||
*/ | ||
private static final ThreadLocal<Integer> THREAD_LOCAL = ThreadLocal.withInitial(() -> 0); | ||
|
||
public static void main(String[] args) { | ||
|
||
new Thread(() -> { | ||
System.out.println(Thread.currentThread().getName() + ":THREAD_LOCAL = " + THREAD_LOCAL.get()); | ||
THREAD_LOCAL.set(1); | ||
System.out.println(Thread.currentThread().getName() + ":THREAD_LOCAL = " + THREAD_LOCAL.get()); | ||
}, "t1").start(); | ||
|
||
new Thread(() -> { | ||
System.out.println(Thread.currentThread().getName() + ":THREAD_LOCAL = " + THREAD_LOCAL.get()); | ||
THREAD_LOCAL.set(2); | ||
System.out.println(Thread.currentThread().getName() + ":THREAD_LOCAL = " + THREAD_LOCAL.get()); | ||
}, "t2").start(); | ||
|
||
new Thread(() -> { | ||
System.out.println(Thread.currentThread().getName() + ":THREAD_LOCAL = " + THREAD_LOCAL.get()); | ||
THREAD_LOCAL.set(3); | ||
System.out.println(Thread.currentThread().getName() + ":THREAD_LOCAL = " + THREAD_LOCAL.get()); | ||
}, "t3").start(); | ||
|
||
System.out.println(Thread.currentThread().getName() + ":THREAD_LOCAL = " + THREAD_LOCAL.get()); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
package xyz.xuminghai.base; | ||
|
||
import java.util.Arrays; | ||
import java.util.LinkedList; | ||
import java.util.List; | ||
import java.util.concurrent.TimeUnit; | ||
|
||
/** | ||
* 2023/3/15 21:19 星期三<br/> | ||
* | ||
* <h1>线程栈信息</h1> | ||
* | ||
* @author xuMingHai | ||
*/ | ||
public class ThreadStackDemo { | ||
|
||
public static void main(String[] args) { | ||
Thread t1 = new Thread(() -> { | ||
List<String> list = new LinkedList<>(); | ||
list.add(""); | ||
try { | ||
TimeUnit.SECONDS.sleep(1); | ||
} | ||
catch (InterruptedException e) { | ||
throw new RuntimeException(e); | ||
} | ||
list.add("1"); | ||
System.out.println("list = " + list); | ||
list.clear(); | ||
}, "t1"); | ||
|
||
t1.start(); | ||
|
||
// 直到线程死亡停止循环 | ||
while (t1.isAlive()) { | ||
System.out.println(Arrays.toString(t1.getStackTrace())); | ||
} | ||
} | ||
|
||
} |
34 changes: 34 additions & 0 deletions
34
src/main/java/xyz/xuminghai/base/ThreadUncaughtExceptionDemo.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
package xyz.xuminghai.base; | ||
|
||
import java.util.concurrent.TimeUnit; | ||
|
||
/** | ||
* 2023/3/15 21:45 星期三<br/> | ||
* | ||
* <h1>线程未捕获异常示例</h1> | ||
* | ||
* @author xuMingHai | ||
*/ | ||
public class ThreadUncaughtExceptionDemo { | ||
|
||
public static void main(String[] args) { | ||
|
||
Thread t1 = new Thread(() -> { | ||
throw new IllegalStateException(); | ||
}, "t1"); | ||
|
||
// 设置线程因为未捕获的异常导致线程终止处理器 | ||
t1.setUncaughtExceptionHandler((t, e) -> System.out.println(t.getName() + ":出现异常了")); | ||
|
||
t1.start(); | ||
|
||
try { | ||
TimeUnit.SECONDS.sleep(3); | ||
} | ||
catch (InterruptedException e) { | ||
throw new RuntimeException(e); | ||
} | ||
|
||
} | ||
|
||
} |