concurrent_study

This commit is contained in:
Zerroi 2024-04-19 16:04:28 +08:00
commit 518a399355
102 changed files with 8816 additions and 0 deletions

38
.gitignore vendored Normal file
View File

@ -0,0 +1,38 @@
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/
### IntelliJ IDEA ###
.idea/modules.xml
.idea/jarRepositories.xml
.idea/compiler.xml
.idea/libraries/
*.iws
*.iml
*.ipr
### Eclipse ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
!**/src/main/**/build/
!**/src/test/**/build/
### VS Code ###
.vscode/
### Mac OS ###
.DS_Store

8
.idea/.gitignore vendored Normal file
View File

@ -0,0 +1,8 @@
# Default ignored files
/shelf/
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

8
.idea/encodings.xml Normal file
View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding" defaultCharsetForPropertiesFiles="UTF-8">
<file url="file://$PROJECT_DIR$/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/src/main/resources" charset="UTF-8" />
<file url="PROJECT" charset="UTF-8" />
</component>
</project>

42
.idea/leetcode/editor.xml Normal file
View File

@ -0,0 +1,42 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="LeetcodeEditor">
<option name="projectConfig">
<map>
<entry key="$USER_HOME$/AppData/Local/Temp/leetcode/editor/cn/[1]两数之和.java">
<value>
<LeetcodeEditor>
<option name="contentPath" value="$USER_HOME$/AppData/Local/Temp/leetcode/editor/cn/doc/content/[1]两数之和.md" />
<option name="frontendQuestionId" value="leetcode.cn1" />
<option name="host" value="leetcode.cn" />
<option name="path" value="$USER_HOME$/AppData/Local/Temp/leetcode/editor/cn/[1]两数之和.java" />
<option name="titleSlug" value="two-sum" />
</LeetcodeEditor>
</value>
</entry>
<entry key="$USER_HOME$/AppData/Local/Temp/leetcode/editor/cn/[34]在排序数组中查找元素的第一个和最后一个位置.java">
<value>
<LeetcodeEditor>
<option name="contentPath" value="$USER_HOME$/AppData/Local/Temp/leetcode/editor/cn/doc/content/[34]在排序数组中查找元素的第一个和最后一个位置.md" />
<option name="frontendQuestionId" value="leetcode.cn34" />
<option name="host" value="leetcode.cn" />
<option name="path" value="$USER_HOME$/AppData/Local/Temp/leetcode/editor/cn/[34]在排序数组中查找元素的第一个和最后一个位置.java" />
<option name="titleSlug" value="find-first-and-last-position-of-element-in-sorted-array" />
</LeetcodeEditor>
</value>
</entry>
<entry key="$USER_HOME$/AppData/Local/Temp/leetcode/editor/cn/[42]接雨水.java">
<value>
<LeetcodeEditor>
<option name="contentPath" value="$USER_HOME$/AppData/Local/Temp/leetcode/editor/cn/doc/content/[42]接雨水.md" />
<option name="frontendQuestionId" value="leetcode.cn42" />
<option name="host" value="leetcode.cn" />
<option name="path" value="$USER_HOME$/AppData/Local/Temp/leetcode/editor/cn/[42]接雨水.java" />
<option name="titleSlug" value="trapping-rain-water" />
</LeetcodeEditor>
</value>
</entry>
</map>
</option>
</component>
</project>

View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="LeetcodeEditorStatistics">
<option name="statistics">
<map>
<entry key="leetcode.cn">
<value>
<Statistics>
<option name="easy" value="50" />
<option name="hard" value="3" />
<option name="medium" value="65" />
<option name="questionTotal" value="3511" />
<option name="solvedTotal" value="118" />
</Statistics>
</value>
</entry>
</map>
</option>
</component>
</project>

14
.idea/misc.xml Normal file
View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="MavenProjectsManager">
<option name="originalFiles">
<list>
<option value="$PROJECT_DIR$/pom.xml" />
</list>
</option>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>

124
.idea/uiDesigner.xml Normal file
View File

@ -0,0 +1,124 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Palette2">
<group name="Swing">
<item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />
</item>
<item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
</item>
<item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.svg" removable="false" auto-create-binding="false" can-attach-label="true">
<default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />
</item>
<item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" />
<initial-values>
<property name="text" value="Button" />
</initial-values>
</item>
<item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="RadioButton" />
</initial-values>
</item>
<item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="CheckBox" />
</initial-values>
</item>
<item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
<initial-values>
<property name="text" value="Label" />
</initial-values>
</item>
<item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" />
</item>
<item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" />
</item>
<item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1">
<preferred-size width="-1" height="20" />
</default-constraints>
</item>
<item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" />
</item>
<item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" />
</item>
</group>
</component>
</project>

6
.idea/vcs.xml Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

36
pom.xml Normal file
View File

@ -0,0 +1,36 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.zerroi</groupId>
<artifactId>concurrent_study</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.10</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.openjdk.jol/jol-core -->
<dependency>
<groupId>org.openjdk.jol</groupId>
<artifactId>jol-core</artifactId>
<version>0.16</version>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,35 @@
package com.zerroi.alternateprint;
import lombok.extern.slf4j.Slf4j;
@Slf4j(topic = "c.Test1")
public class Test1 {
static final Object lock = new Object();
static boolean isRun = false;
public static void main(String[] args) {
Thread t1 = new Thread(() -> {
synchronized (lock) {
while (!isRun) {
try {
lock.wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
log.debug("1");
}
}, "t1");
Thread t2 = new Thread(() -> {
synchronized (lock) {
log.debug("2");
isRun = true;
lock.notify();
}
}, "t2");
t1.start();
t2.start();
}
}

View File

@ -0,0 +1,44 @@
package com.zerroi.alternateprint;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
@Slf4j(topic = "c.Test2")
public class Test2 {
private static final ReentrantLock lock = new ReentrantLock();
private static final Condition condition = lock.newCondition();
static boolean isRun = false;
public static void main(String[] args) {
Thread t1 = new Thread(() -> {
lock.lock();
try {
while (!isRun) {
try {
condition.await();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
log.debug("1");
} finally {
lock.unlock();
}
}, "t1");
Thread t2 = new Thread(() -> {
lock.lock();
try {
log.debug("2");
isRun = true;
condition.signal();
} finally {
lock.unlock();
}
}, "t2");
t1.start();
t2.start();
}
}

View File

@ -0,0 +1,24 @@
package com.zerroi.alternateprint;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.locks.LockSupport;
@Slf4j(topic = "c.Test3")
public class Test3 {
public static void main(String[] args) {
Thread t1 = new Thread(() -> {
LockSupport.park();
log.debug("1");
}, "t1");
Thread t2 = new Thread(() -> {
log.debug("2");
LockSupport.unpark(t1);
}, "t2");
t1.start();
t2.start();
// waknjd
}
}

View File

@ -0,0 +1,49 @@
package com.zerroi.alternateprint;
import lombok.extern.slf4j.Slf4j;
@Slf4j(topic = "c.Test4")
public class Test4 {
public static void main(String[] args) {
WaitAndNotify waitAndNotify = new WaitAndNotify(5, 1);
new Thread(() -> {
waitAndNotify.print("a", 1, 2);
},"t1").start();
new Thread(() -> {
waitAndNotify.print("b", 2, 3);
},"t2").start();
new Thread(() -> {
waitAndNotify.print("c", 3, 1);
},"t3").start();
}
}
@Slf4j(topic = "c.WaitAndNotify")
class WaitAndNotify {
public void print(String str, int waitFlag, int nextFlag) {
for (int i = 0; i < loop; i++) {
synchronized (this) {
while (waitFlag != flag) {
try {
this.wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
log.debug(str);
flag = nextFlag;
this.notifyAll();
}
}
}
public WaitAndNotify(int loop, int flag) {
this.loop = loop;
this.flag = flag;
}
private final int loop;
private int flag;
}

View File

@ -0,0 +1,60 @@
package com.zerroi.alternateprint;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
public class Test5 {
public static void main(String[] args) throws InterruptedException {
AwaitSignal awaitSignal = new AwaitSignal(5);
Condition a = awaitSignal.newCondition();
Condition b = awaitSignal.newCondition();
Condition c = awaitSignal.newCondition();
new Thread(() -> {
awaitSignal.print("a", a, b);
}, "A").start();
new Thread(() -> {
awaitSignal.print("b", b, c);
}, "B").start();
new Thread(() -> {
awaitSignal.print("c", c, a);
}, "C").start();
Thread.sleep(1000);
awaitSignal.lock();
try {
a.signal();
} finally {
awaitSignal.unlock();
}
}
}
@Slf4j(topic = "c.AwaitSignal")
class AwaitSignal extends ReentrantLock {
private final int loop;
public AwaitSignal(int loop) {
this.loop = loop;
}
public void print(String str, Condition cur, Condition next) {
for (int i = 0; i < loop; i++) {
lock();
try {
cur.await();
log.debug(str);
next.signal();
} catch (InterruptedException e) {
throw new RuntimeException(e);
} finally {
unlock();
}
}
}
}

View File

@ -0,0 +1,50 @@
package com.zerroi.alternateprint;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.locks.LockSupport;
public class Test6 {
static Thread t1;
static Thread t2;
static Thread t3;
public static void main(String[] args) {
ParkUnpark parkUnpark = new ParkUnpark(5);
t1 = new Thread(() -> {
parkUnpark.print("A", t2);
}, "t1");
t2 = new Thread(() -> {
parkUnpark.print("B", t3);
}, "t2");
t3 = new Thread(() -> {
parkUnpark.print("C", t1);
}, "t3");
t1.start();
t2.start();
t3.start();
LockSupport.unpark(t1);
}
}
@Slf4j(topic = "c.ParkUnpark")
class ParkUnpark {
public void print(String str, Thread next) {
for (int i = 0; i < loop; i++) {
LockSupport.park();
log.info(str);
LockSupport.unpark(next);
}
}
private final int loop;
public ParkUnpark(int loop) {
this.loop = loop;
}
}

View File

@ -0,0 +1,18 @@
package com.zerroi.charpter05;
import static java.lang.Thread.sleep;
public class Test1 {
volatile static boolean run = true;
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(() -> {
while (run) {
}
}, "t1");
t1.start();
sleep(1000);
System.out.println("stop t1");
run = false;
}
}

View File

@ -0,0 +1,50 @@
package com.zerroi.charpter06;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.atomic.AtomicInteger;
import static java.lang.Thread.sleep;
@Slf4j(topic = "c.LockCas")
public class LockCas {
private AtomicInteger state = new AtomicInteger(0);
public void lock() {
while (true) {
if (state.compareAndSet(0, 1)) {
break;
}
}
}
public void unlock() {
log.debug("unlock....");
state.set(0);
}
public static void main(String[] args) {
LockCas lock = new LockCas();
new Thread(() -> {
log.debug("begin...");
lock.lock();
try {
log.debug("lock");
sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
} finally {
lock.unlock();
}
}, "t1").start();
new Thread(() -> {
log.debug("begin...");
lock.lock();
try {
log.debug("lock");
} finally {
lock.unlock();
}
}, "t2").start();
}
}

View File

@ -0,0 +1,90 @@
package com.zerroi.charpter06;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
public class Test0 {
public static void main(String[] args) {
Account account = new AccountCas(10000);
Account.demo(account);
}
}
class AccountCas implements Account {
private AtomicInteger balance;
public AccountCas(int balance) {
this.balance = new AtomicInteger(balance);
}
@Override
public Integer getBalance() {
return balance.get();
}
@Override
public void withdraw(Integer amount) {
/*while (true) {
int pre = balance.get();
int next = pre - amount;
boolean isUpdated = balance.compareAndSet(pre, next);
if (isUpdated) {
break;
}
}*/
balance.getAndAdd(-1 * amount);
}
}
interface Account {
// 获取余额
Integer getBalance();
// 取款
void withdraw(Integer amount);
/**
* 方法内会启动 1000 个线程每个线程做 -10 的操作
* 如果初始余额为 10000 那么正确的结果应当是 0
*/
static void demo(Account account) {
List<Thread> ts = new ArrayList<>();
long start = System.nanoTime();
for (int i = 0; i < 1000; i++) {
ts.add(new Thread(() -> {
account.withdraw(10);
}));
}
ts.forEach(Thread::start);
ts.forEach(t -> {
try {
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
long end = System.nanoTime();
System.out.println(account.getBalance()
+ " cost: " + (end - start) / 1000_000 + " ms");
}
}
class AccountUnsafe implements Account {
private Integer balance;
public AccountUnsafe(Integer balance) {
this.balance = balance;
}
@Override
public Integer getBalance() {
return balance;
}
@Override
public void withdraw(Integer amount) {
balance -= amount;
}
}

View File

@ -0,0 +1,29 @@
package com.zerroi.charpter06;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.IntUnaryOperator;
public class Test1 {
public static void main(String[] args) {
AtomicInteger integer = new AtomicInteger(5);
// System.out.println(integer.incrementAndGet());
// System.out.println(integer.getAndIncrement());
// System.out.println(integer.getAndAdd(5));
// System.out.println(integer.addAndGet(5));
// System.out.println(integer.updateAndGet(x -> x * 5));
System.out.println(updateAndGet(integer, pre -> pre / 2));
System.out.println(integer.get());
}
public static int updateAndGet(AtomicInteger integer, IntUnaryOperator operator) {
while (true) {
int pre = integer.get();
int next = operator.applyAsInt(pre);
if (integer.compareAndSet(pre, next)) {
return next;
}
}
}
}

View File

@ -0,0 +1,69 @@
package com.zerroi.charpter06;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;
public class Test2 {
public static void main(String[] args) {
DecimalAccount.demo(new DecimalAccountCas(new BigDecimal("10000")));
}
}
class DecimalAccountCas implements DecimalAccount {
private AtomicReference<BigDecimal> balance;
public DecimalAccountCas(BigDecimal balance) {
this.balance = new AtomicReference<>(balance);
}
@Override
public BigDecimal getBalance() {
return balance.get();
}
@Override
public void withdraw(BigDecimal amount) {
while (true) {
BigDecimal pre = balance.get();
BigDecimal next = pre.subtract(amount);
if (balance.compareAndSet(pre, next)) {
break;
}
}
}
}
interface DecimalAccount {
// 获取余额
BigDecimal getBalance();
// 取款
void withdraw(BigDecimal amount);
/**
* 方法内会启动 1000 个线程每个线程做 -10 的操作
* 如果初始余额为 10000 那么正确的结果应当是 0
*/
static void demo(DecimalAccount account) {
List<Thread> ts = new ArrayList<>();
long start = System.nanoTime();
for (int i = 0; i < 1000; i++) {
ts.add(new Thread(() -> {
account.withdraw(BigDecimal.valueOf(10));
}));
}
ts.forEach(Thread::start);
ts.forEach(t -> {
try {
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
long end = System.nanoTime();
System.out.println(account.getBalance()
+ " cost: " + (end - start) / 1000_000 + " ms");
}
}

View File

@ -0,0 +1,16 @@
package com.zerroi.charpter06;
import java.util.concurrent.atomic.AtomicReference;
import static java.lang.Thread.sleep;
public class Test3 {
static AtomicReference<String> ref = new AtomicReference<>("A");
public static void main(String[] args) throws InterruptedException {
System.out.println("start....");
String pre = ref.get();
sleep(1000);
System.out.println(ref.compareAndSet(pre, "A"));
System.out.println(ref.get());
}
}

View File

@ -0,0 +1,37 @@
package com.zerroi.charpter06;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.atomic.AtomicStampedReference;
import static java.lang.Thread.sleep;
@Slf4j(topic = "c.Test4")
public class Test4 {
static AtomicStampedReference<String> reference = new AtomicStampedReference<>("A", 0);
public static void main(String[] args) throws InterruptedException {
log.debug("main start....");
int stamp = reference.getStamp();
log.debug("{}", stamp);
String pre = reference.getReference();
other();
sleep(1000);
log.debug("A->C {}", reference.compareAndSet(pre, "C", stamp, stamp + 1));
}
private static void other() throws InterruptedException {
new Thread(() -> {
int stamp = reference.getStamp();
log.debug("{}", stamp);
log.debug("A->B {}", reference.compareAndSet(reference.getReference(), "B", stamp, stamp + 1));
}, "t1").start();
sleep(500);
new Thread(() -> {
int stamp = reference.getStamp();
log.debug("{}", stamp);
log.debug("B->A {}", reference.compareAndSet(reference.getReference(), "A", stamp, stamp + 1));
}, "t2").start();
}
}

View File

@ -0,0 +1,48 @@
package com.zerroi.charpter06;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.atomic.AtomicMarkableReference;
@Slf4j(topic = "c.Test5")
public class Test5 {
public static void main(String[] args) throws InterruptedException {
GarbageBag bag = new GarbageBag("装满了垃圾");
// 参数2 mark 可以看作一个标记表示垃圾袋满了
AtomicMarkableReference<GarbageBag> ref = new AtomicMarkableReference<>(bag, true);
log.debug("主线程 start...");
GarbageBag prev = ref.getReference();
log.debug(prev.toString());
new Thread(() -> {
log.debug("打扫卫生的线程 start...");
bag.setDesc("空垃圾袋");
while (!ref.compareAndSet(bag, bag, true, false)) {
}
log.debug(bag.toString());
}).start();
Thread.sleep(1000);
log.debug("主线程想换一只新垃圾袋?");
boolean success = ref.compareAndSet(prev, new GarbageBag("空垃圾袋"), true, false);
log.debug("换了么?" + success);
log.debug(ref.getReference().toString());
}
}
class GarbageBag {
String desc;
public GarbageBag(String desc) {
this.desc = desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
@Override
public String toString() {
return super.toString() + " " + desc;
}
}

View File

@ -0,0 +1,24 @@
package com.zerroi.charpter06;
import lombok.ToString;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
@Slf4j(topic = "c.Test6")
public class Test6 {
public static void main(String[] args) {
Student student = new Student();
AtomicReferenceFieldUpdater<Student, String> updater =
AtomicReferenceFieldUpdater.newUpdater(Student.class, String.class, "name");
System.out.println(updater.compareAndSet(student, null, "张三"));
System.out.println(student);
}
}
@ToString
class Student {
volatile String name;
}

View File

@ -0,0 +1,50 @@
package com.zerroi.charpter06;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.LongAdder;
import java.util.function.Consumer;
import java.util.function.Supplier;
public class Test7 {
public static void main(String[] args) {
for (int i = 0; i < 5; i++) {
demo(
() -> new AtomicLong(0),
AtomicLong::getAndIncrement
);
}
for (int i = 0; i < 5; i++) {
demo(
LongAdder::new,
LongAdder::increment
);
}
}
private static <T> void demo(Supplier<T> adderSupplier, Consumer<T> action) {
T adder = adderSupplier.get();
long start = System.nanoTime();
List<Thread> ts = new ArrayList<>();
// 4 个线程每人累加 50
for (int i = 0; i < 40; i++) {
ts.add(new Thread(() -> {
for (int j = 0; j < 500000; j++) {
action.accept(adder);
}
}));
}
ts.forEach(t -> t.start());
ts.forEach(t -> {
try {
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
long end = System.nanoTime();
System.out.println(adder + " cost:" + (end - start)/1000_000);
}
}

View File

@ -0,0 +1,51 @@
package com.zerroi.charpter06;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import sun.misc.Unsafe;
public class Test8 {
public static void main(String[] args) {
Account.demo(new MyAtomicInteger(10000));
}
}
@Getter
@Slf4j(topic = "c.MyAtomicInteger")
class MyAtomicInteger implements Account{
private volatile int value;
private static long valueOffset;
static final Unsafe UNSAFE;
public MyAtomicInteger(int value) {
this.value = value;
}
static {
UNSAFE = UnsafeAccessor.getUnsafe();
try {
valueOffset = UNSAFE.objectFieldOffset(MyAtomicInteger.class.getDeclaredField("value"));
} catch (NoSuchFieldException e) {
log.error("error: ", e);
throw new RuntimeException(e);
}
}
public void decrement(int amount) {
while (true) {
int pre = this.value;
int next = pre - amount;
if (UNSAFE.compareAndSwapInt(this, valueOffset, pre, next)) {
break;
}
}
}
@Override
public Integer getBalance() {
return getValue();
}
@Override
public void withdraw(Integer amount) {
decrement(amount);
}
}

View File

@ -0,0 +1,30 @@
package com.zerroi.charpter06;
import lombok.Data;
import sun.misc.Unsafe;
import java.lang.reflect.Field;
public class TestUnSafe {
public static void main(String[] args) throws Exception {
Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
theUnsafe.setAccessible(true);
Unsafe unsafe = (Unsafe) theUnsafe.get(null);
System.out.println(unsafe);
// 获取域的偏移地址
long idOffset = unsafe.objectFieldOffset(Teacher.class.getDeclaredField("id"));
long nameOffset = unsafe.objectFieldOffset(Teacher.class.getDeclaredField("name"));
Teacher teacher = new Teacher();
unsafe.compareAndSwapInt(teacher, idOffset, 0, 1);
unsafe.compareAndSwapObject(teacher, nameOffset, null, "Rocky");
System.out.println(teacher);
}
}
@Data
class Teacher {
volatile int id;
volatile String name;
}

View File

@ -0,0 +1,23 @@
package com.zerroi.charpter06;
import lombok.Getter;
import sun.misc.Unsafe;
import java.lang.reflect.Field;
public class UnsafeAccessor {
@Getter
private static final Unsafe unsafe;
static {
try {
Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
theUnsafe.setAccessible(true);
unsafe = (Unsafe) theUnsafe.get(null);
} catch (NoSuchFieldException | IllegalAccessException e) {
throw new Error(e);
}
}
}

View File

@ -0,0 +1,35 @@
package com.zerroi.charpter07;
import lombok.extern.slf4j.Slf4j;
import java.text.SimpleDateFormat;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAccessor;
@Slf4j(topic = "c.Test1")
public class Test1 {
public static void main(String[] args) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
for (int i = 0; i < 10; i++) {
new Thread(() -> {
TemporalAccessor parse = formatter.parse("1951-04-21");
log.debug("data:{}", parse);
}, "t" + i).start();
}
}
public static void test() {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
for (int i = 0; i < 10; i++) {
new Thread(() -> {
synchronized (sdf) {
try {
log.debug("{}", sdf.parse("1951-04-21"));
} catch (Exception e) {
log.error(String.valueOf(e));
}
}
}).start();
}
}
}

View File

@ -0,0 +1,367 @@
package com.zerroi.charpter07;
import lombok.extern.slf4j.Slf4j;
import java.sql.*;
import java.util.Map;
import java.util.Properties;
import java.util.Random;
import java.util.concurrent.Executor;
import java.util.concurrent.atomic.AtomicIntegerArray;
public class Test2 {
public static void main(String[] args) {
Pool pool = new Pool(2);
for (int i = 0; i < 5; i++) {
new Thread(() -> {
Connection connection = pool.borrow();
try {
Thread.sleep(new Random().nextInt(1000));
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
pool.returnConn(connection);
}, "t" + i).start();
}
}
}
@Slf4j(topic = "c.Pool")
class Pool {
// 连接池的大小
private final int poolSize;
// 连接对象数组
private Connection[] connections;
// 连接状态数组 0->空闲1->繁忙
private AtomicIntegerArray status;
public Pool(int poolSize) {
this.poolSize = poolSize;
this.status = new AtomicIntegerArray(new int[poolSize]);
this.connections = new Connection[poolSize];
for (int i = 0; i < poolSize; i++) {
connections[i] = new MockConnection("连接对象" + (i+1));
}
}
// 借连接
public Connection borrow() {
while (true) {
for (int i = 0; i < poolSize; i++) {
if (status.get(i) == 0) {
if (status.compareAndSet(i, 0, 1)) {
log.debug("获取连接:{}", connections[i]);
return connections[i];
}
}
}
// 如果没有空闲连接当前线程进入等待
synchronized (this) {
try {
log.debug("等待连接....");
this.wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}
// 返还连接
public void returnConn(Connection conn) {
for (int i = 0; i < connections.length; i++) {
if (connections[i] == conn) {
status.set(i, 0);
synchronized (this) {
log.debug("归还连接:{}", conn);
this.notifyAll();
}
break;
}
}
}
}
class MockConnection implements Connection {
private String name;
public MockConnection(String name) {
this.name = name;
}
@Override
public String toString() {
return "MockConnection{" +
"name='" + name + '\'' +
'}';
}
@Override
public Statement createStatement() throws SQLException {
return null;
}
@Override
public PreparedStatement prepareStatement(String sql) throws SQLException {
return null;
}
@Override
public CallableStatement prepareCall(String sql) throws SQLException {
return null;
}
@Override
public String nativeSQL(String sql) throws SQLException {
return null;
}
@Override
public void setAutoCommit(boolean autoCommit) throws SQLException {
}
@Override
public boolean getAutoCommit() throws SQLException {
return false;
}
@Override
public void commit() throws SQLException {
}
@Override
public void rollback() throws SQLException {
}
@Override
public void close() throws SQLException {
}
@Override
public boolean isClosed() throws SQLException {
return false;
}
@Override
public DatabaseMetaData getMetaData() throws SQLException {
return null;
}
@Override
public void setReadOnly(boolean readOnly) throws SQLException {
}
@Override
public boolean isReadOnly() throws SQLException {
return false;
}
@Override
public void setCatalog(String catalog) throws SQLException {
}
@Override
public String getCatalog() throws SQLException {
return null;
}
@Override
public void setTransactionIsolation(int level) throws SQLException {
}
@Override
public int getTransactionIsolation() throws SQLException {
return 0;
}
@Override
public SQLWarning getWarnings() throws SQLException {
return null;
}
@Override
public void clearWarnings() throws SQLException {
}
@Override
public Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException {
return null;
}
@Override
public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
return null;
}
@Override
public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
return null;
}
@Override
public Map<String, Class<?>> getTypeMap() throws SQLException {
return null;
}
@Override
public void setTypeMap(Map<String, Class<?>> map) throws SQLException {
}
@Override
public void setHoldability(int holdability) throws SQLException {
}
@Override
public int getHoldability() throws SQLException {
return 0;
}
@Override
public Savepoint setSavepoint() throws SQLException {
return null;
}
@Override
public Savepoint setSavepoint(String name) throws SQLException {
return null;
}
@Override
public void rollback(Savepoint savepoint) throws SQLException {
}
@Override
public void releaseSavepoint(Savepoint savepoint) throws SQLException {
}
@Override
public Statement createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
return null;
}
@Override
public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
return null;
}
@Override
public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
return null;
}
@Override
public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException {
return null;
}
@Override
public PreparedStatement prepareStatement(String sql, int[] columnIndexes) throws SQLException {
return null;
}
@Override
public PreparedStatement prepareStatement(String sql, String[] columnNames) throws SQLException {
return null;
}
@Override
public Clob createClob() throws SQLException {
return null;
}
@Override
public Blob createBlob() throws SQLException {
return null;
}
@Override
public NClob createNClob() throws SQLException {
return null;
}
@Override
public SQLXML createSQLXML() throws SQLException {
return null;
}
@Override
public boolean isValid(int timeout) throws SQLException {
return false;
}
@Override
public void setClientInfo(String name, String value) throws SQLClientInfoException {
}
@Override
public void setClientInfo(Properties properties) throws SQLClientInfoException {
}
@Override
public String getClientInfo(String name) throws SQLException {
return null;
}
@Override
public Properties getClientInfo() throws SQLException {
return null;
}
@Override
public Array createArrayOf(String typeName, Object[] elements) throws SQLException {
return null;
}
@Override
public Struct createStruct(String typeName, Object[] attributes) throws SQLException {
return null;
}
@Override
public void setSchema(String schema) throws SQLException {
}
@Override
public String getSchema() throws SQLException {
return null;
}
@Override
public void abort(Executor executor) throws SQLException {
}
@Override
public void setNetworkTimeout(Executor executor, int milliseconds) throws SQLException {
}
@Override
public int getNetworkTimeout() throws SQLException {
return 0;
}
@Override
public <T> T unwrap(Class<T> iface) throws SQLException {
return null;
}
@Override
public boolean isWrapperFor(Class<?> iface) throws SQLException {
return false;
}
}

View File

@ -0,0 +1,74 @@
package com.zerroi.charpter08;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.AbstractQueuedSynchronizer;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class TestAQS {
public static void main(String[] args) {
ReentrantLock lock = new ReentrantLock();
}
}
class MyLock implements Lock {
class MySync extends AbstractQueuedSynchronizer {
@Override
protected boolean tryAcquire(int arg) {
if (compareAndSetState(0, 1)) {
setExclusiveOwnerThread(Thread.currentThread());
return true;
}
return false;
}
@Override
protected boolean tryRelease(int arg) {
setExclusiveOwnerThread(null);
setState(0);
return true;
}
@Override
protected boolean isHeldExclusively() {
return getState() == 1;
}
public Condition newCondition() {
return new ConditionObject();
}
}
private MySync sync = new MySync();
@Override
public void lock() {
sync.acquire(1);
}
@Override
public void lockInterruptibly() throws InterruptedException {
sync.acquireInterruptibly(1);
}
@Override
public boolean tryLock() {
return sync.tryAcquire(1);
}
@Override
public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
return false;
}
@Override
public void unlock() {
}
@Override
public Condition newCondition() {
return null;
}
}

View File

@ -0,0 +1,75 @@
package com.zerroi.charpter08;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.LongAdder;
import java.util.function.BiConsumer;
import java.util.function.Supplier;
import java.util.stream.Collectors;
public class TestConcurrentHashMap {
static final String ALPHA = "abcedfghijklmnopqrstuvwxyz";
public static void main(String[] args) {
demo(
// 创建 map 集合
// 创建 ConcurrentHashMap 对不对
() -> new ConcurrentHashMap<String, LongAdder>(),
// 进行计数
(map, words) -> {
for (String word : words) {
LongAdder value = map.computeIfAbsent(word, (key) -> new LongAdder());
value.increment();
/*Integer counter = map.get(word);
int newValue = counter == null ? 1 : counter + 1;
map.put(word, newValue);*/
}
}
);
}
private static <V> void demo(Supplier<Map<String, V>> supplier,
BiConsumer<Map<String, V>, List<String>> consumer) {
Map<String, V> counterMap = supplier.get();
List<Thread> ts = new ArrayList<>();
for (int i = 1; i <= 26; i++) {
int idx = i;
Thread thread = new Thread(() -> {
List<String> words = readFromFile(idx);
consumer.accept(counterMap, words);
});
ts.add(thread);
}
ts.forEach(t -> t.start());
ts.forEach(t -> {
try {
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
System.out.println(counterMap);
}
public static List<String> readFromFile(int i) {
ArrayList<String> words = new ArrayList<>();
try (BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream("tmp/"
+ i + ".txt")))) {
while (true) {
String word = in.readLine();
if (word == null) {
break;
}
words.add(word);
}
return words;
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}

View File

@ -0,0 +1,29 @@
package com.zerroi.charpter08;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveTask;
public class TestForkJoin {
public static void main(String[] args) {
ForkJoinPool pool = new ForkJoinPool(4);
System.out.println(pool.invoke(new MyTask(5)));
}
}
class MyTask extends RecursiveTask<Integer> {
private int n;
public MyTask(int n) {
this.n = n;
}
@Override
protected Integer compute() {
if (n == 1) {
return 1;
}
MyTask t1 = new MyTask(n - 1);
t1.fork();
return n + t1.join();
}
}

View File

@ -0,0 +1,192 @@
package com.zerroi.charpter08;
import lombok.extern.slf4j.Slf4j;
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.HashSet;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
@Slf4j(topic = "c.TestPool")
public class TestPool {
public static void main(String[] args) {
ThreadPool threadPool = new ThreadPool(2, 1000, TimeUnit.MILLISECONDS, 10, (queue, task) -> {
});
for (int i = 0; i < 15; i++) {
int j = i;
threadPool.execute(() -> {
log.debug("{}", j);
});
}
}
}
@FunctionalInterface
interface RejectPolicy<T> {
void reject(BlockingQueue<T> queue, T task);
}
@Slf4j(topic = "c.ThreadPool")
class ThreadPool {
private BlockingQueue<Runnable> taskQueue;
private HashSet<Worker> workers = new HashSet<>();
private int coreThreads;
private long timeout;
private TimeUnit timeUnit;
private RejectPolicy<Runnable> rejectPolicy;
public synchronized void execute(Runnable task) {
if (workers.size() < coreThreads) {
log.debug("新增worker:{},{}", workers, task);
Worker worker = new Worker(task);
workers.add(worker);
worker.start();
} else {
log.debug("加入任务队列:{}", task);
// taskQueue.put(task);
taskQueue.tryPut(rejectPolicy, task);
}
}
public ThreadPool(int coreThreads, long timeout, TimeUnit timeUnit, int queueCapacity, RejectPolicy<Runnable> rejectPolicy) {
this.coreThreads = coreThreads;
this.timeout = timeout;
this.timeUnit = timeUnit;
this.taskQueue = new BlockingQueue<>(queueCapacity);
this.rejectPolicy = rejectPolicy;
}
class Worker extends Thread {
private Runnable task;
public Worker(Runnable task) {
this.task = task;
}
@Override
public void run() {
while (task != null || (task = taskQueue.take()) != null) {
try {
log.debug("正在执行任务:{}", task);
task.run();
} catch (Exception e) {
e.printStackTrace();
} finally {
task = null;
}
}
synchronized (workers) {
log.debug("worker被移除{}", this);
workers.remove(this);
}
}
}
}
class BlockingQueue<T> {
// 任务队列
private Deque<T> queue = new ArrayDeque<>();
//
private ReentrantLock lock = new ReentrantLock();
// 生产者条件变量
private Condition fullWaitSet = lock.newCondition();
// 消费者条件变量
private Condition emptyWaitSet = lock.newCondition();
// 队列容量
private int capacity;
public BlockingQueue(int queueCapacity) {
this.capacity = queueCapacity;
}
// 带超时的阻塞获取
public T poll(long timeout, TimeUnit unit) {
lock.lock();
try {
long nanos = unit.toNanos(timeout);
while (queue.isEmpty()) {
nanos = emptyWaitSet.awaitNanos(nanos);
}
fullWaitSet.signal();
return queue.removeFirst();
} catch (InterruptedException e) {
throw new RuntimeException(e);
} finally {
lock.unlock();
}
}
// 阻塞获取
T take() {
lock.lock();
try {
while (queue.isEmpty()) {
emptyWaitSet.await();
}
fullWaitSet.signal();
return queue.removeFirst();
} catch (InterruptedException e) {
throw new RuntimeException(e);
} finally {
lock.unlock();
}
}
// 阻塞添加
void put(T task) {
lock.lock();
try {
while (queue.size() == capacity) {
fullWaitSet.await();
}
queue.addLast(task);
emptyWaitSet.signal();
} catch (InterruptedException e) {
throw new RuntimeException(e);
} finally {
lock.unlock();
}
}
boolean offer(T task, long timeout, TimeUnit timeUnit) {
lock.lock();
try {
long nanos = timeUnit.toNanos(timeout);
while (queue.size() == capacity) {
if (nanos <= 0) {
return false;
}
nanos = fullWaitSet.awaitNanos(nanos);
}
queue.addLast(task);
emptyWaitSet.signal();
return true;
} catch (InterruptedException e) {
throw new RuntimeException(e);
} finally {
lock.unlock();
}
}
// 队列大小
int size() {
return queue.size();
}
public void tryPut(RejectPolicy<T> rejectPolicy, T task) {
lock.lock();
try {
if (queue.size() == capacity) {
rejectPolicy.reject(this, task);
} else {
queue.addLast(task);
emptyWaitSet.signal();
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}

View File

@ -0,0 +1,64 @@
package com.zerroi.charpter08;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class TestReadWriteLock {
public static void main(String[] args) {
DataContainer dataContainer = new DataContainer(new Object());
new Thread(() -> {
dataContainer.write(new Object());
}, "t1").start();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
new Thread(() -> {
dataContainer.write(new Object());
}, "t2").start();
}
}
@Slf4j
class DataContainer {
private Object data;
private ReentrantReadWriteLock rw = new ReentrantReadWriteLock();
private ReentrantReadWriteLock.ReadLock r = rw.readLock();
private ReentrantReadWriteLock.WriteLock w = rw.writeLock();
public DataContainer(Object data) {
this.data = data;
}
public Object read() {
log.debug("获取读锁");
r.lock();
try {
log.debug("读取");
Thread.sleep(1000);
return data;
} catch (InterruptedException e) {
throw new RuntimeException(e);
} finally {
log.debug("释放读锁");
r.unlock();
}
}
public void write(Object o) {
log.debug("获取写锁");
w.lock();
try {
log.debug("写入");
Thread.sleep(1000);
this.data = o;
} catch (InterruptedException e) {
throw new RuntimeException(e);
} finally {
log.debug("释放写锁");
w.unlock();
}
}
}

View File

@ -0,0 +1,29 @@
package com.zerroi.charpter08;
import lombok.extern.slf4j.Slf4j;
import java.time.DayOfWeek;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
@Slf4j
public class TestSchedule {
public static void main(String[] args) {
ScheduledExecutorService pool = Executors.newScheduledThreadPool(1);
LocalDateTime now = LocalDateTime.now();
LocalDateTime time = now.withHour(14).withMinute(36).withSecond(10).withNano(0).with(DayOfWeek.SUNDAY);
if (now.isAfter(time)) {
time = time.plusWeeks(1L);
}
// 当前时间与周四时间差值
long initialDelay = Duration.between(now, time).toMillis();
// 每周间隔
long period = 7 * 100 * 60 * 24 * 60;
pool.scheduleAtFixedRate(() -> {
log.debug("每周四18:00:08");
}, initialDelay, period, TimeUnit.MILLISECONDS);
}
}

View File

@ -0,0 +1,50 @@
package com.zerroi.charpter08;
import lombok.extern.slf4j.Slf4j;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
@Slf4j
public class TestShutdown {
public static void main(String[] args) {
ExecutorService pool = Executors.newFixedThreadPool(2);
Future<String> result1 = pool.submit(() -> {
log.debug("task1 Running");
Thread.sleep(1000);
log.debug("FINISHED 1");
return "task1 ok!!!";
});
Future<String> result2 = pool.submit(() -> {
log.debug("task2 Running");
Thread.sleep(1000);
log.debug("FINISHED 2");
return "task2 ok!!!";
});
Future<String> result3 = pool.submit(() -> {
log.debug("task3 Running");
Thread.sleep(1000);
log.debug("FINISHED 3");
return "task3 ok!!!";
});
/*pool.shutdown();
try {
pool.awaitTermination(3, TimeUnit.SECONDS);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}*/
log.debug("SHUTDOWN NOW!");
List<Runnable> list = pool.shutdownNow();
list.forEach(Runnable::run);
log.debug("OTHER");
}
}

View File

@ -0,0 +1,71 @@
package com.zerroi.charpter08;
import lombok.extern.slf4j.Slf4j;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.*;
@Slf4j
public class TestSubmit {
public static void main(String[] args) throws ExecutionException, InterruptedException {
ExecutorService pool = Executors.newFixedThreadPool(1);
String s = pool.invokeAny(Arrays.asList(
() -> {
log.debug("BEGIN 111");
Thread.sleep(1000);
log.debug("END");
return "1";
},
() -> {
log.debug("BEGIN 2222");
Thread.sleep(500);
log.debug("END");
return "2";
},
() -> {
log.debug("BEGIN 3333");
Thread.sleep(2000);
return "3";
}
));
log.debug("{}", s);
}
private static void invokeAll(ExecutorService pool) throws InterruptedException {
List<Future<String>> futures = pool.invokeAll(Arrays.asList(
() -> {
log.debug("begin");
Thread.sleep(1000);
return "1";
},
() -> {
log.debug("begin");
Thread.sleep(500);
return "2";
},
() -> {
log.debug("begin");
Thread.sleep(2000);
return "3";
}
));
futures.forEach(f -> {
try {
log.debug("{}", f.get());
} catch (InterruptedException | ExecutionException e) {
throw new RuntimeException(e);
}
});
}
private static void extracted(ExecutorService executorService) throws InterruptedException, ExecutionException {
Future<String> result = executorService.submit(() -> {
log.debug("Running");
Thread.sleep(1000);
return "ok!!!";
});
String res = result.get();
log.debug("res:{}", res);
}
}

View File

@ -0,0 +1,25 @@
package com.zerroi.charpter08;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicInteger;
@Slf4j
public class TestThreadPoolExecutor {
public static void main(String[] args) {
ExecutorService executorService = Executors.newFixedThreadPool(2, new ThreadFactory() {
private AtomicInteger atomicInteger = new AtomicInteger(1);
@Override
public Thread newThread(Runnable r) {
return new Thread(r, "mypool_t" + atomicInteger.getAndAdd(1));
}
});
log.debug("teststst");
executorService.execute(() -> System.out.println(1));
executorService.execute(() -> System.out.println(2));
executorService.execute(() -> System.out.println(3));
}
}

View File

@ -0,0 +1,61 @@
package com.zerroi.charpter08;
import lombok.extern.slf4j.Slf4j;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.*;
@Slf4j
public class TestTimer {
public static void main(String[] args) {
ExecutorService pool = Executors.newFixedThreadPool(1);
Future<Boolean> future = pool.submit(() -> {
log.debug("START..");
int i = 1 / 0;
return true;
});
try {
Boolean res = future.get();
log.debug("RES:{}", res);
} catch (InterruptedException | ExecutionException e) {
throw new RuntimeException(e);
}
}
private static void withfix(ScheduledExecutorService pool) {
pool.scheduleWithFixedDelay(() -> {
log.debug("RUNNING....");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}, 1, 1, TimeUnit.SECONDS);
}
private static void extracted1(ScheduledExecutorService pool) {
pool.scheduleAtFixedRate(() -> {
log.debug("RUNNING....");
try {
Thread.sleep(500);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}, 1, 1, TimeUnit.SECONDS);
}
private static void extracted(ScheduledExecutorService pool) {
pool.schedule(() -> {
log.debug("TASK 1");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}, 1, TimeUnit.SECONDS);
pool.schedule(() -> {log.debug("TASK 2");}, 1, TimeUnit.SECONDS);
}
}

View File

@ -0,0 +1,34 @@
package com.zerroi.pattern;
import lombok.extern.slf4j.Slf4j;
@Slf4j(topic = "c.RunSequentially")
public class RunSequentially {
static final Object lock = new Object();
static boolean t2Ran = false;
public static void main(String[] args) {
Thread t1 = new Thread(() -> {
synchronized (lock) {
while (!t2Ran) {
try {
lock.wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
log.debug("t1");
}, "t1");
Thread t2 = new Thread(() -> {
synchronized (lock) {
log.debug("t2");
t2Ran = true;
lock.notify();
}
}, "t2");
t1.start();
t2.start();
}
}

View File

@ -0,0 +1,17 @@
package com.zerroi.pattern;
import java.util.concurrent.locks.LockSupport;
public class RunSequentially2 {
public static void main(String[] args) {
Thread t1 = new Thread(() -> {
LockSupport.park();
System.out.println("t1");
}, "t1");
Thread t2 = new Thread(() -> {
System.out.println("t2");
LockSupport.unpark(t1);
}, "t2");
}
}

View File

@ -0,0 +1,71 @@
package com.zerroi.pattern;
import lombok.extern.slf4j.Slf4j;
@Slf4j(topic = "c.RunSequentially3")
public class RunSequentially3 {
private static Object lock = new Object();
private static int count = 0;
public static void main(String[] args) {
Thread t1 = new Thread(() -> {
for (int i = 0; i < 5; i++) {
synchronized (lock) {
while (count % 3 != 0) {
try {
lock.wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
log.debug("a");
count++;
lock.notifyAll();
}
}
}, "t1");
Thread t2 = new Thread(() -> {
for (int i = 0; i < 5; i++) {
synchronized (lock) {
while (count % 3 != 1) {
try {
lock.wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
log.debug("b");
count++;
lock.notifyAll();
}
}
}, "t2");
Thread t3 = new Thread(() -> {
for (int i = 0; i < 5; i++) {
synchronized (lock) {
while (count % 3 != 2) {
try {
lock.wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
log.debug("c");
count++;
lock.notifyAll();
}
}
}, "t3");
t1.start();
t2.start();
t3.start();
}
}
/*
a 1
b 2
c 3
* */

View File

@ -0,0 +1,65 @@
package com.zerroi.pattern;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
public class RunSequentially4 {
public static void main(String[] args) throws InterruptedException {
AwaitSignal awaitSignal = new AwaitSignal(5);
Condition condition1 = awaitSignal.newCondition();
Condition condition2 = awaitSignal.newCondition();
Condition condition3 = awaitSignal.newCondition();
new Thread(() -> {
try {
awaitSignal.print("a", condition1, condition2);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}).start();
new Thread(() -> {
try {
awaitSignal.print("b", condition2, condition3);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}).start();
new Thread(() -> {
try {
awaitSignal.print("c", condition3, condition1);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}).start();
Thread.sleep(1000);
awaitSignal.lock();
try {
System.out.println("开始。。。。");
condition1.signal();
} finally {
awaitSignal.unlock();
}
}
}
class AwaitSignal extends ReentrantLock {
private int loop;
public AwaitSignal(int loop) {
this.loop = loop;
}
public void print(String s, Condition cur, Condition next) throws InterruptedException {
for (int i = 0; i < loop; i++) {
lock();
try {
cur.await();
System.out.println(s);
next.signal();
} finally {
unlock();
}
}
}
}

View File

@ -0,0 +1,43 @@
package com.zerroi.pattern;
import java.util.concurrent.locks.LockSupport;
public class RunSequentially5 {
static Thread t1;
static Thread t2;
static Thread t3;
public static void main(String[] args) {
ParkUnpark parkUnpark = new ParkUnpark(5);
t1 = new Thread(() -> {
parkUnpark.print("a", t2);
}, "t1");
t2 = new Thread(() -> {
parkUnpark.print("b", t3);
}, "t2");
t3 = new Thread(() -> {
parkUnpark.print("c", t1);
}, "t3");
t1.start();
t2.start();
t3.start();
LockSupport.unpark(t1);
}
}
class ParkUnpark {
private int loop;
public ParkUnpark(int loop) {
this.loop = loop;
}
public void print(String s, Thread next) {
for (int i = 0; i < loop; i++) {
LockSupport.park();
System.out.println(s);
LockSupport.unpark(next);
}
}
}

View File

@ -0,0 +1,11 @@
package com.zerroi.pattern;
import java.util.ArrayList;
import java.util.List;
public class Test {
public static void main(String[] args) {
List<Integer> list = new ArrayList<>();
list.add(1);
}
}

View File

@ -0,0 +1,50 @@
package com.zerroi.pattern;
import lombok.extern.slf4j.Slf4j;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
@Slf4j
public class TestStarvation {
static final List<String> MENU = Arrays.asList("地三鲜", "宫保鸡丁", "辣子鸡丁", "烤鸡翅");
static Random RANDOM = new Random();
static String cooking() {
return MENU.get(RANDOM.nextInt(MENU.size()));
}
public static void main(String[] args) {
ExecutorService waiterPool = Executors.newFixedThreadPool(1);
ExecutorService cookerPool = Executors.newFixedThreadPool(1);
waiterPool.execute(() -> {
log.debug("处理点餐...");
Future<String> f = cookerPool.submit(() -> {
log.debug("做菜");
return cooking();
});
try {
log.debug("上菜: {}", f.get());
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
});
waiterPool.execute(() -> {
log.debug("处理点餐...");
Future<String> f = cookerPool.submit(() -> {
log.debug("做菜");
return cooking();
});
try {
log.debug("上菜: {}", f.get());
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
});
}
}

View File

@ -0,0 +1,49 @@
package com.zerroi.test;
import lombok.extern.slf4j.Slf4j;
@Slf4j(topic = "c.OverallPlanning")
public class OverallPlanning {
public static void main(String[] args) {
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
log.debug("洗水壶");
sleep(1);
log.debug("烧开水");
sleep(15);
}
}, "t1");
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
log.debug("洗茶壶");
sleep(1);
log.debug("洗茶杯");
sleep(2);
log.debug("拿茶叶");
sleep(1);
try {
t1.join();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
log.debug("泡茶");
}
}, "t2");
t1.start();
t2.start();
}
private static void sleep(int time) {
try {
Thread.sleep(time);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}

View File

@ -0,0 +1,66 @@
package com.zerroi.test;
import lombok.extern.slf4j.Slf4j;
public class PhilosopherDinning {
public static void main(String[] args) {
Chopstick c1 = new Chopstick("1");
Chopstick c2 = new Chopstick("2");
Chopstick c3 = new Chopstick("3");
Chopstick c4 = new Chopstick("4");
Chopstick c5 = new Chopstick("5");
new Philosopher("苏格拉底", c1, c2).start();
new Philosopher("柏拉图", c2, c3).start();
new Philosopher("亚里士多德", c3, c4).start();
new Philosopher("赫拉克利特", c4, c5).start();
new Philosopher("阿基米德", c1, c5).start();
}
}
@Slf4j(topic = "c.Philosopher")
class Philosopher extends Thread{
Chopstick left;
Chopstick right;
public Philosopher(String name, Chopstick left, Chopstick right) {
super(name);
this.left = left;
this.right = right;
}
@Override
public void run() {
while (true) {
synchronized (left) {
synchronized (right) {
eat();
}
}
}
}
private void eat() {
log.debug("eat.....");
try {
// 思考过程
sleep(50);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
class Chopstick {
private String name;
@Override
public String toString() {
return "Chopstick{" +
"name='" + name + '\'' +
'}';
}
public Chopstick(String name) {
this.name = name;
}
}

View File

@ -0,0 +1,76 @@
package com.zerroi.test;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.locks.ReentrantLock;
public class PhilosopherDinning2 {
public static void main(String[] args) {
Chopstick2 c1 = new Chopstick2("1");
Chopstick2 c2 = new Chopstick2("2");
Chopstick2 c3 = new Chopstick2("3");
Chopstick2 c4 = new Chopstick2("4");
Chopstick2 c5 = new Chopstick2("5");
new Philosopher2("苏格拉底", c1, c2).start();
new Philosopher2("柏拉图", c2, c3).start();
new Philosopher2("亚里士多德", c3, c4).start();
new Philosopher2("赫拉克利特", c4, c5).start();
new Philosopher2("阿基米德", c5, c1).start();
}
}
@Slf4j(topic = "c.Philosopher2")
class Philosopher2 extends Thread{
Chopstick2 left;
Chopstick2 right;
public Philosopher2(String name, Chopstick2 left, Chopstick2 right) {
super(name);
this.left = left;
this.right = right;
}
@Override
public void run() {
while (true) {
if (left.tryLock()) {
try {
if (right.tryLock()) {
try {
eat();
} finally {
right.unlock();
}
}
} finally {
left.unlock();
}
}
}
}
private void eat() {
log.debug("eat.....");
try {
// 思考过程
sleep(500);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
class Chopstick2 extends ReentrantLock {
private String name;
@Override
public String toString() {
return "Chopstick{" +
"name='" + name + '\'' +
'}';
}
public Chopstick2(String name) {
this.name = name;
}
}

View File

@ -0,0 +1,39 @@
package com.zerroi.test;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.locks.ReentrantLock;
@Slf4j(topic = "c.ReentrantLockTest")
public class ReentrantLockTest {
static ReentrantLock lock = new ReentrantLock();
public static void main(String[] args) {
lock.lock();
try {
log.debug("enter main");
m1();
m2();
} finally {
lock.unlock();
}
}
public static void m1() {
lock.lock();
try {
log.debug("enter m1");
} finally {
lock.unlock();
}
}
public static void m2() {
lock.lock();
try {
log.debug("enter m2");
} finally {
lock.unlock();
}
}
}

View File

@ -0,0 +1,41 @@
package com.zerroi.test;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.locks.ReentrantLock;
@Slf4j(topic = "c.ReentrantLockTest2")
public class ReentrantLockTest2 {
static ReentrantLock lock = new ReentrantLock();
public static void main(String[] args) {
Thread t1 = new Thread(() -> {
try {
// 如果没有竞争此方法就会获取lock对象锁
// 如果有竞争进入阻塞队列可以被其他线程interrupt方法打断
log.debug("尝试获取锁");
lock.lock();
} catch (Exception e) {
e.printStackTrace();
log.debug("没有获取到锁,返回");
return;
}
try {
log.debug("获取到锁");
}finally {
lock.unlock();
}
}, "t1");
lock.lock();
t1.start();
try {
Thread.sleep(1000);
log.debug("打断t1");
t1.interrupt();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}

View File

@ -0,0 +1,38 @@
package com.zerroi.test;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;
@Slf4j(topic = "c.ReentrantLockTest3")
public class ReentrantLockTest3 {
static ReentrantLock lock = new ReentrantLock();
public static void main(String[] args) {
Thread t1 = new Thread(() -> {
// 尝试获取锁
log.debug("尝试获取锁");
try {
if (!lock.tryLock(1, TimeUnit.SECONDS)) {
log.debug("获取不到锁");
return;
}
} catch (InterruptedException e) {
e.printStackTrace();
log.debug("获取不到锁");
return;
}
try {
log.debug("获得到锁");
} finally {
lock.unlock();
}
}, "t1");
log.debug("获得到锁");
lock.lock();
t1.start();
}
}

View File

@ -0,0 +1,31 @@
package com.zerroi.test;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
@Slf4j(topic = "c.ReentrantLockTest")
public class ReentrantLockTest4 {
static ReentrantLock lock = new ReentrantLock();
public static void main(String[] args) {
// 创建一个新的条件变量休息室
Condition condition1 = lock.newCondition();
Condition condition2 = lock.newCondition();
lock.lock();
// 进入休息室等待
try {
condition1.await();
} catch (InterruptedException e) {
throw new RuntimeException(e);
} finally {
lock.unlock();
}
// 叫醒condition1中的某一个线程
condition1.signal();
// 叫醒condition1中的所有线程
condition1.signalAll();
}
}

View File

@ -0,0 +1,24 @@
package com.zerroi.test;
import lombok.extern.slf4j.Slf4j;
@Slf4j(topic = "c.Test12")
public class Test12 {
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
while (true) {
if (Thread.currentThread().isInterrupted()) {
break;
}
}
}
}, "t1");
t1.start();
Thread.sleep(1000);
log.debug("interrupt");
t1.interrupt();
}
}

View File

@ -0,0 +1,28 @@
package com.zerroi.test;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.locks.LockSupport;
import static java.lang.Thread.sleep;
@Slf4j(topic = "c.Test13")
public class Test13 {
public static void main(String[] args) throws InterruptedException {
test3();
}
private static void test3() throws InterruptedException {
Thread t1 = new Thread(() -> {
log.debug("park...");
LockSupport.park();
log.debug("unpark...");
log.debug("打断状态:{}", Thread.currentThread().isInterrupted());
LockSupport.park();
log.debug("unpark...");
}, "t1");
t1.start();
sleep(500);
t1.interrupt();
}
}

View File

@ -0,0 +1,100 @@
package com.zerroi.test;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import java.util.Hashtable;
import java.util.Map;
import java.util.Set;
public class Test14 {
public static void main(String[] args) {
}
}
@Slf4j(topic = "c.Resident")
class Resident extends Thread{
@Override
public void run() {
GuardedObject guardedObject = MailBoxes.createGuardedObject();
log.debug("开始收信id:{}", guardedObject.getId());
Object mail = guardedObject.get(5000L);
log.debug("收到信id:{},内容:{}", guardedObject.getId(), mail);
}
}
@Slf4j(topic = "c.Postman")
class Postman extends Thread {
private int mailId;
private String mail;
public Postman(int mailId, String mail) {
this.mailId = mailId;
this.mail =mail;
}
@Override
public void run() {
GuardedObject guardedObject = MailBoxes.getGuardedObject(mailId);
guardedObject.complete(guardedObject);
}
}
class MailBoxes {
private static int id = 1;
private static Map<Integer, GuardedObject> map = new Hashtable<>();
private static synchronized int generateId() {
return id++;
}
public static GuardedObject createGuardedObject() {
GuardedObject guardedObject = new GuardedObject(generateId());
map.put(guardedObject.getId(), guardedObject);
return guardedObject;
}
public Set<Integer> getIds() {
return map.keySet();
}
public static GuardedObject getGuardedObject(int id) {
return map.get(id);
}
}
@Slf4j(topic = "c.GuardedObject")
class GuardedObject {
@Getter
private int id;
private Object response;
public GuardedObject(int id) {
this.id = id;
}
public Object get(Long timeout) {
synchronized (this) {
long begin = System.currentTimeMillis();
long passedTime = 0;
while (response == null) {
long waitTime = timeout - passedTime;
if (timeout - passedTime <= 0) {
break;
}
try {
this.wait(waitTime);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
passedTime = System.currentTimeMillis() - begin;
log.debug("timePassed: {}, object is null {}",
passedTime, response == null);
}
}
return response;
}
public void complete(GuardedObject guardedObject) {
}
}

View File

@ -0,0 +1,103 @@
package com.zerroi.test;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import java.util.LinkedList;
public class Test15 {
public static void main(String[] args) throws InterruptedException {
MessageQueue messageQueue = new MessageQueue(2);
for (int i = 0; i < 3; i++) {
int id = i;
new Thread(() -> {
messageQueue.put(new Message(id, "" + id));
}, "producer" + i).start();
}
new Thread(()-> {
while (true) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
Message message = messageQueue.get();
}
}, "consumer").start();
}
}
@Slf4j(topic = "c.MessageQueue")
class MessageQueue {
// 消息的队列集合
private LinkedList<Message> list = new LinkedList<>();
// 消息的容量
private int capacity;
public MessageQueue(int capacity) {
this.capacity = capacity;
}
// 获取消息
public Message get() {
// 检查队列是否为空
synchronized (list) {
while (list.isEmpty()) {
try {
log.debug("队列为空,消费者线程等待");
list.wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
// 从队列头部获取消息返回
Message message = list.removeFirst();
log.debug("消费者消费了一个消息:{}", message);
list.notifyAll();
return message;
}
}
// 存入消息
public void put(Message message) {
synchronized (list) {
// 检查队列是否已满
while (list.size() == capacity) {
log.debug("队列已满,生产者线程等待");
try {
list.wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
list.addLast(message);
log.debug("生产者生产了一个消息:{}", message);
list.notifyAll();
}
}
}
@Data
class Message {
private int id;
private Object value;
public Message(int id, Object value) {
this.id = id;
this.value = value;
}
@Override
public String toString() {
return "Message{" +
"id=" + id +
", value=" + value +
'}';
}
}

View File

@ -0,0 +1,43 @@
package com.zerroi.test;
import lombok.extern.slf4j.Slf4j;
import static java.lang.Thread.sleep;
@Slf4j(topic = "c.Test16")
public class Test16 {
public static void main(String[] args) {
Object A = new Object();
Object B = new Object();
Thread t1 = new Thread(() -> {
synchronized (A) {
log.debug("lock A");
try {
sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
synchronized (B) {
log.debug("lock B");
log.debug("操作...");
}
}
}, "t1");
Thread t2 = new Thread(() -> {
synchronized (B) {
log.debug("lock B");
try {
sleep(500);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
synchronized (A) {
log.debug("lock A");
log.debug("操作...");
}
}
}, "t2");
t1.start();
t2.start();
}
}

View File

@ -0,0 +1,46 @@
package com.zerroi.test;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
public class Test17 {
public static void main(String[] args) {
ReentrantLock lock = new ReentrantLock();
Condition condition = lock.newCondition();
// 等待线程
Runnable waitingTask = () -> {
lock.lock();
try {
System.out.println("Waiting thread is waiting...");
condition.await(); // 等待条件变量
System.out.println("Waiting thread is awake!");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
};
// 通知线程
Runnable notifyingTask = () -> {
lock.lock();
try {
Thread.sleep(2000); // 模拟一些操作
System.out.println("Notifying thread is notifying...");
condition.signal(); // 唤醒等待线程
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
};
// 创建线程并启动
Thread waitingThread = new Thread(waitingTask);
Thread notifyingThread = new Thread(notifyingTask);
waitingThread.start();
notifyingThread.start();
}
}

View File

@ -0,0 +1,18 @@
package com.zerroi.test;
public class Test4 {
public static void main(String[] args) {
method1(10);
}
private static void method1(int i) {
int y = i + 1;
Object m = method2();
System.out.println("m = " + m);
}
private static Object method2() {
return new Object();
}
}

View File

@ -0,0 +1,17 @@
package com.zerroi.test;
public class Test5 {
public static void main(String[] args) {
Thread t1 = new Thread("t1") {
@Override
public void run() {
System.out.println("running");
}
};
System.out.println("t1.getState() = " + t1.getState());
t1.start();
t1.start();
System.out.println("t1.getState() = " + t1.getState());
}
}

View File

@ -0,0 +1,22 @@
package com.zerroi.test;
import lombok.extern.slf4j.Slf4j;
@Slf4j(topic = "c.Test6")
public class Test6 {
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread("t1") {
@Override
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
};
t1.start();
t1.interrupt();
log.debug("t1 state: {}", t1.getState());
}
}

View File

@ -0,0 +1,28 @@
package com.zerroi.test;
import lombok.extern.slf4j.Slf4j;
@Slf4j(topic = "c.Test7")
public class Test7 {
public static void main(String[] args) {
Runnable task1 = () -> {
int count = 0;
for (; ; ) {
System.out.println("---->1 " + count++);
}
};
Runnable task2 = () -> {
int count = 0;
for (; ; ) {
// Thread.yield();
System.out.println(" ---->2 " + count++);
}
};
Thread t1 = new Thread(task1, "t1");
Thread t2 = new Thread(task2, "t2");
t1.setPriority(Thread.MIN_PRIORITY);
t2.setPriority(Thread.MAX_PRIORITY);
t1.start();
t2.start();
}
}

View File

@ -0,0 +1,31 @@
package com.zerroi.test;
import lombok.extern.slf4j.Slf4j;
import static java.lang.Thread.sleep;
@Slf4j(topic = "c.Test8")
public class Test8 {
static int r = 0;
public static void main(String[] args) throws InterruptedException {
test1();
}
private static void test1() throws InterruptedException {
log.debug("开始");
Thread t1 = new Thread(() -> {
log.debug("开始");
try {
sleep(1);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
log.debug("结束");
r = 10;
// log.debug("结果为:{}", r);
});
t1.start();
t1.join();
log.debug("结果为:{}", r);
log.debug("结束");
}
}

View File

@ -0,0 +1,26 @@
package com.zerroi.test;
public class Test9 {
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(() -> {
}, "t1");
}
private static void extracted() throws InterruptedException {
Thread thread = new Thread(() -> {
try {
System.out.println("Sleeping for 5 seconds...");
Thread.sleep(5000);
System.out.println("Done sleeping.");
} catch (InterruptedException e) {
e.printStackTrace();
}
});
thread.start();
Thread.sleep(2000); // Wait for the thread to start sleeping.
thread.interrupt(); // Interrupt the thread.
System.out.println("thread.isInterrupted() = " + thread.isInterrupted());
}
}

View File

@ -0,0 +1,28 @@
package com.zerroi.test;
import lombok.extern.slf4j.Slf4j;
import org.openjdk.jol.info.ClassLayout;
@Slf4j(topic = "c.TestBiased")
public class TestBiased {
public static void main(String[] args) throws InterruptedException {
Dog dog = new Dog();
int i = dog.hashCode(); // 会禁用偏向锁
String s = ClassLayout.parseInstance(dog).toPrintable();
log.debug(s);
System.out.println("--------------------------------");
synchronized (dog) {
log.debug(ClassLayout.parseInstance(dog).toPrintable());
}
System.out.println("--------------------------------");
log.debug(ClassLayout.parseInstance(new Dog()).toPrintable());
}
}
class Dog {
}

View File

@ -0,0 +1,46 @@
package com.zerroi.test;
import lombok.extern.slf4j.Slf4j;
import org.openjdk.jol.info.ClassLayout;
@Slf4j(topic = "c.TestBiased")
public class TestBiased2 {
public static void main(String[] args) throws InterruptedException {
Cat cat = new Cat();
new Thread(() -> {
log.debug(ClassLayout.parseInstance(cat).toPrintable());
System.out.println("--------------------------------");
synchronized (cat) {
log.debug(ClassLayout.parseInstance(cat).toPrintable());
}
System.out.println("--------------------------------");
log.debug(ClassLayout.parseInstance(new Dog()).toPrintable());
synchronized (TestBiased2.class) {
TestBiased2.class.notify();
}
}, "t1").start();
System.out.println("--------------------------------");
new Thread(() -> {
synchronized (TestBiased2.class) {
try {
TestBiased2.class.wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
log.debug(ClassLayout.parseInstance(cat).toPrintable());
System.out.println("--------------------------------");
synchronized (cat) {
log.debug(ClassLayout.parseInstance(cat).toPrintable());
}
System.out.println("--------------------------------");
log.debug(ClassLayout.parseInstance(new Dog()).toPrintable());
}, "t2").start();
}
}
class Cat {
}

View File

@ -0,0 +1,45 @@
package com.zerroi.test;
import lombok.extern.slf4j.Slf4j;
import org.openjdk.jol.info.ClassLayout;
import java.util.Vector;
@Slf4j(topic = "c.TestBiased3")
public class TestBiased3 {
public static void main(String[] args) {
Vector<Dog> list = new Vector<>();
Thread t1 = new Thread(() -> {
for (int i = 0; i < 30; i++) {
Dog d = new Dog();
list.add(d);
synchronized (d) {
log.debug(i + "\t" + ClassLayout.parseInstance(d).toPrintable());
}
}
synchronized (list) {
list.notify();
}
}, "t1");
t1.start();
Thread t2 = new Thread(() -> {
synchronized (list) {
try {
list.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
log.debug("===============> ");
for (int i = 0; i < 30; i++) {
Dog d = list.get(i);
log.debug(i + "\t" + ClassLayout.parseInstance(d).toPrintable());
synchronized (d) {
log.debug(i + "\t" + ClassLayout.parseInstance(d).toPrintable());
}
log.debug(i + "\t" + ClassLayout.parseInstance(d).toPrintable());
}
}, "t2");
t2.start();
}
}

View File

@ -0,0 +1,26 @@
package com.zerroi.test;
public class TestFrames {
public static void main(String[] args) {
Thread t1 = new Thread(){
@Override
public void run() {
method1(20);
}
};
t1.setName("t1");
t1.start();
t1.isInterrupted();
method1(10);
}
private static void method1(int i) {
int y = i + 1;
Object m = method2();
System.out.println("m = " + m);
}
private static Object method2() {
return new Object();
}
}

View File

@ -0,0 +1,41 @@
package com.zerroi.test;
import lombok.extern.slf4j.Slf4j;
import static java.lang.Thread.sleep;
@Slf4j(topic = "c.TestJoin")
public class TestJoin {
static int r1 = 0;
static int r2 = 0;
public static void main(String[] args) throws InterruptedException {
test2();
}
private static void test2() throws InterruptedException {
Thread t1 = new Thread(() -> {
try {
sleep(1);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
r1 = 10;
});
Thread t2 = new Thread(() -> {
try {
sleep(2);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
r2 = 20;
});
long start = System.currentTimeMillis();
t1.start();
t2.start();
t1.join();
t2.join();
long end = System.currentTimeMillis();
log.debug("r1: {} r2: {} cost: {}", r1, r2, end - start);
}
}

View File

@ -0,0 +1,10 @@
package com.zerroi.test;
import lombok.extern.slf4j.Slf4j;
@Slf4j(topic = "c.TestWaitAndNotify")
public class TestWaitAndNotify {
public static void main(String[] args) {
}
}

View File

@ -0,0 +1,39 @@
package com.zerroi.test;
import lombok.extern.slf4j.Slf4j;
import static java.lang.Thread.sleep;
@Slf4j(topic = "c.TestWaitNotify")
public class TestWaitNotify {
final static Object obj = new Object();
public static void main(String[] args) throws InterruptedException {
new Thread(() -> {
synchronized (obj) {
log.debug("执行....");
try {
obj.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
log.debug("其它代码...."); // 断点
}
},"t1").start();
new Thread(() -> {
synchronized (obj) {
log.debug("执行....");
try {
obj.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
log.debug("其它代码...."); // 断点
}
},"t2").start();
sleep(500L);
log.debug("唤醒 obj 上其它线程");
synchronized (obj) {
obj.notifyAll(); // 唤醒obj上所有等待线程 断点
}
}
}

View File

@ -0,0 +1,43 @@
package com.zerroi.test;
import lombok.extern.slf4j.Slf4j;
@Slf4j(topic = "c.TwoPhaseCommit")
public class TwoPhaseCommit {
public static void main(String[] args) throws InterruptedException {
TwoPhase twoPhase = new TwoPhase();
twoPhase.start();
Thread.sleep(3500);
twoPhase.stop();
}
}
@Slf4j(topic = "c.TwoPhaseCommit")
class TwoPhase {
private Thread monitor;
// 启动监控线程
public void start() {
monitor = new Thread(() -> {
while (true) {
// 拿到当前线程
Thread currentThread = Thread.currentThread();
if (currentThread.isInterrupted()) {
log.debug("料理后事");
break;
}
try {
Thread.sleep(1000);
log.debug("执行监控记录");
} catch (InterruptedException e) {
log.error(String.valueOf(e));
// currentThread.interrupt();
}
}
});
monitor.start();
}
// 终止监控线程
public void stop() {
monitor.interrupt();
}
}

View File

@ -0,0 +1,20 @@
package com.zerroi.test;
import lombok.extern.slf4j.Slf4j;
@Slf4j(topic = "c.TestMultiThread")
public class test3 {
public static void main(String[] args) {
new Thread(() -> {
while (true) {
log.debug("running");
}
}, "t1").start();
new Thread(() -> {
while (true) {
log.debug("running");
}
}, "t2").start();
}
}

View File

@ -0,0 +1,36 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!-- 控制台输出 -->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%highlight(%d{HH:mm:ss.SSS} [%thread]) [%-5level] %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<!-- 设置颜色 -->
<conversionRule conversionWord="highlight" converterClass="org.example.HighlightConverter" />
<!-- 根日志级别为DEBUG输出到控制台 -->
<root level="DEBUG">
<appender-ref ref="CONSOLE" />
</root>
<!-- 设置颜色 -->
<turboFilter class="ch.qos.logback.classic.turbo.DynamicThresholdFilter">
<Key>threadColor</Key>
<DefaultThreshold>DEBUG</DefaultThreshold>
<MDCValueLevelPair>
<value>Thread-1</value>
<level>TRACE</level>
</MDCValueLevelPair>
<!-- 在此添加更多的线程ID和对应的日志级别 -->
</turboFilter>
<!-- 根日志级别为DEBUG输出到控制台 -->
<root level="DEBUG">
<appender-ref ref="CONSOLE" />
</root>
</configuration>

200
tmp/1.txt Normal file
View File

@ -0,0 +1,200 @@
l
d
u
d
k
y
i
o
x
l
t
r
x
o
v
p
j
e
g
k
t
l
i
h
i
p
k
z
k
p
l
n
s
m
c
i
l
u
e
c
p
n
q
t
e
v
x
l
c
f
l
l
y
d
s
d
n
w
d
v
b
i
m
x
o
f
a
p
y
m
b
d
t
g
q
f
b
u
k
m
m
k
v
q
e
w
r
j
r
i
k
x
t
j
w
d
c
z
b
e
k
o
b
a
o
y
e
c
f
o
w
n
n
f
d
m
e
x
h
d
b
a
f
j
g
t
a
k
e
l
e
w
q
i
h
j
m
y
x
w
r
b
b
f
p
q
s
g
o
b
b
h
i
j
d
k
u
v
w
p
g
n
u
k
n
i
x
s
g
m
n
f
u
t
z
d
q
k
n
g
x
o
t
r
m
x
x
w
m
e
n
i
s
w
m
q
k
q
a
h

200
tmp/10.txt Normal file
View File

@ -0,0 +1,200 @@
d
s
g
o
v
x
i
i
e
t
r
w
d
c
d
c
m
q
v
a
q
w
p
n
r
f
b
v
e
n
s
q
p
p
q
j
g
h
u
m
a
x
f
l
x
m
a
j
n
w
z
y
u
w
e
c
k
p
h
q
j
f
r
y
r
l
l
y
e
g
w
j
o
w
n
p
l
n
s
v
x
e
y
i
j
e
w
v
d
n
p
q
d
u
v
z
h
x
w
e
i
p
y
w
j
m
k
g
c
x
i
p
o
i
s
t
v
x
c
s
b
o
s
p
q
t
b
y
g
g
s
q
c
t
d
u
p
z
u
m
o
c
e
f
l
g
x
z
t
c
y
l
l
k
c
n
p
i
k
r
q
h
o
x
j
t
z
e
x
e
t
g
p
s
d
p
n
i
b
u
q
m
h
m
c
s
s
r
g
h
i
e
e
a
a
r
u
z
o
g

200
tmp/11.txt Normal file
View File

@ -0,0 +1,200 @@
o
z
t
c
k
a
k
g
x
j
d
q
e
z
y
d
g
o
j
q
z
e
v
h
r
j
q
w
g
j
q
k
f
q
h
l
y
f
p
p
k
c
y
v
a
k
n
e
c
y
i
q
q
u
x
a
p
p
q
b
f
b
j
g
h
x
z
b
i
f
p
n
t
c
c
f
d
a
d
b
l
y
d
q
g
x
m
u
x
q
x
m
j
v
q
f
h
b
j
g
u
b
e
g
i
z
r
p
q
k
u
j
p
y
o
v
m
t
o
g
a
y
j
v
j
w
a
l
k
g
w
c
r
m
r
q
r
g
o
t
n
m
e
r
p
b
e
g
z
s
k
g
p
i
o
m
a
u
h
r
u
w
q
k
a
c
z
e
h
t
o
n
s
r
a
z
l
k
s
i
t
l
v
x
y
m
d
l
x
w
i
i
z
b
y
j
h
u
u
s

200
tmp/12.txt Normal file
View File

@ -0,0 +1,200 @@
d
a
j
c
x
x
u
i
t
h
a
r
n
m
c
j
w
y
n
h
r
v
y
h
v
h
w
o
x
u
y
y
n
m
p
r
l
k
l
i
m
c
k
j
m
p
k
z
j
u
u
e
f
n
s
b
a
u
y
i
c
t
y
x
d
h
p
s
b
x
o
w
a
e
o
m
r
k
t
q
j
b
s
c
p
v
x
p
o
b
i
z
w
i
a
q
z
q
b
l
c
c
r
x
h
j
u
d
w
i
u
l
k
x
v
a
v
t
x
m
n
p
z
b
a
u
f
w
o
l
k
n
o
a
r
e
x
u
c
s
s
n
x
e
g
j
l
o
m
r
g
f
e
g
h
z
y
w
h
m
l
l
b
g
c
o
s
t
x
e
w
k
y
y
a
r
u
j
o
p
k
c
h
u
y
y
o
y
i
t
o
n
x
t
d
r
a
n
w
t

200
tmp/13.txt Normal file
View File

@ -0,0 +1,200 @@
r
w
o
k
e
g
e
w
q
w
p
l
j
v
g
y
f
x
x
o
a
w
o
y
p
k
s
y
r
o
v
c
u
n
i
y
p
u
i
g
n
o
w
s
f
d
n
m
m
m
h
i
k
j
d
p
s
r
f
n
y
j
h
n
v
m
x
n
q
c
y
b
y
q
v
u
i
a
u
d
k
w
b
o
f
v
s
k
t
r
j
w
b
u
e
r
a
p
r
a
y
k
j
i
g
e
v
c
n
z
o
n
y
p
a
f
p
q
u
v
f
f
k
c
k
k
d
w
h
a
e
k
r
e
r
c
n
m
n
w
b
m
w
g
x
r
u
x
e
o
a
t
n
g
n
y
j
n
k
w
j
f
r
w
q
s
a
z
a
c
y
d
p
u
c
z
o
u
r
v
q
d
g
s
o
w
x
a
e
d
j
n
w
u
u
e
l
v
t
d

200
tmp/14.txt Normal file
View File

@ -0,0 +1,200 @@
q
m
a
u
e
o
z
y
q
e
d
p
y
x
k
t
x
s
s
l
i
o
z
o
j
k
z
m
h
r
w
c
h
l
t
z
p
d
r
l
u
f
n
w
z
v
z
g
r
r
i
e
e
o
q
g
j
r
h
m
r
u
p
v
v
a
c
t
t
t
l
k
w
p
o
c
h
g
g
f
x
b
h
p
l
d
j
y
o
t
r
e
g
a
e
l
b
z
l
f
s
y
n
i
p
b
f
i
m
f
u
x
r
u
h
h
v
s
i
g
o
u
h
q
q
d
h
c
y
g
w
y
q
v
d
n
c
b
c
a
r
w
g
v
z
d
o
c
s
j
m
a
p
a
o
h
j
q
f
h
c
q
g
n
j
b
s
s
e
t
l
d
p
j
x
d
t
e
p
p
i
s
n
r
x
u
b
e
j
b
s
u
a
x
y
i
q
z
z
x

200
tmp/15.txt Normal file
View File

@ -0,0 +1,200 @@
s
c
p
m
g
d
u
v
l
l
w
m
k
d
f
a
c
g
v
d
y
q
k
u
g
b
u
h
m
s
t
g
b
y
e
b
y
y
y
e
a
q
x
d
h
q
e
o
q
p
h
b
m
b
s
n
n
r
j
t
v
p
a
l
s
z
x
x
c
k
t
u
k
n
s
t
v
h
d
j
o
i
p
v
p
q
t
v
p
f
i
n
s
l
h
h
j
h
y
g
v
j
m
f
x
f
o
f
m
p
i
x
d
f
c
f
e
i
f
x
o
d
q
p
w
b
g
y
l
p
v
y
f
i
o
b
f
a
l
r
v
w
k
m
e
z
w
x
i
s
m
n
k
z
s
h
c
b
m
z
q
u
g
l
f
i
f
s
h
h
j
p
t
n
u
e
a
j
v
k
i
e
a
o
a
t
z
n
m
g
c
n
j
e
v
p
s
e
p
q

200
tmp/16.txt Normal file
View File

@ -0,0 +1,200 @@
a
x
v
d
n
s
s
s
g
t
p
t
x
u
d
b
f
z
h
e
k
e
q
r
h
r
l
l
q
r
f
t
j
t
p
k
b
y
j
t
v
j
y
y
t
x
d
s
v
b
l
a
s
d
r
d
b
e
w
l
n
c
e
v
j
b
e
w
a
s
k
j
z
e
a
e
l
r
k
v
v
g
f
p
q
x
q
q
q
b
l
j
i
w
f
u
a
c
e
y
f
e
j
e
c
b
h
f
c
u
w
p
a
b
r
h
w
j
v
m
b
a
l
x
i
t
x
g
t
i
e
u
y
l
x
w
u
e
w
z
g
p
a
q
c
q
l
d
o
m
z
r
e
s
l
j
m
o
s
d
f
z
h
i
v
u
z
o
e
l
p
x
u
k
p
a
z
u
q
r
s
p
g
z
r
b
u
t
a
a
j
n
p
s
o
q
b
h
q
o

200
tmp/17.txt Normal file
View File

@ -0,0 +1,200 @@
m
c
i
b
s
s
k
v
n
e
i
x
v
a
r
g
g
v
d
h
z
r
b
y
q
g
u
x
o
x
x
o
b
f
v
c
v
b
a
w
a
l
z
u
v
l
m
t
j
a
f
r
i
r
y
i
r
d
r
e
x
k
s
r
c
j
o
g
f
e
m
g
w
l
e
h
y
b
g
z
n
b
v
w
v
b
z
j
r
z
v
n
y
p
d
k
u
b
u
p
i
o
b
b
d
o
p
y
r
u
u
t
e
v
d
r
c
c
u
t
l
v
d
v
w
c
e
m
o
i
c
n
f
i
k
m
r
q
w
h
r
v
o
z
w
x
a
k
y
u
l
v
q
a
k
x
s
e
p
f
j
o
a
p
c
u
z
h
s
o
e
j
m
q
m
w
m
x
n
n
q
h
k
l
j
j
l
h
a
y
i
y
p
m
i
d
q
j
m
x

200
tmp/18.txt Normal file
View File

@ -0,0 +1,200 @@
y
t
f
h
t
o
j
o
b
v
k
g
b
w
t
i
r
y
x
v
x
m
s
c
l
u
m
v
q
r
h
h
j
p
k
x
a
t
r
n
m
k
a
x
y
p
y
o
p
z
b
f
q
l
w
x
t
c
x
r
r
r
z
s
l
y
d
f
q
b
m
i
z
u
m
o
f
k
l
g
y
r
f
l
q
s
f
w
v
i
s
x
n
x
n
h
j
v
y
w
j
m
z
x
b
i
k
z
u
n
u
q
z
s
v
j
p
p
b
p
l
h
q
w
l
n
g
t
z
z
x
w
v
w
l
x
r
s
u
p
f
d
r
q
g
m
v
v
c
b
h
n
w
e
b
f
y
y
i
y
o
h
f
e
z
k
l
o
l
r
b
w
h
l
w
w
a
p
z
i
f
f
i
v
z
x
g
q
t
y
n
b
t
i
d
u
h
q
z
l

200
tmp/19.txt Normal file
View File

@ -0,0 +1,200 @@
i
j
u
y
f
l
i
a
y
c
n
y
l
e
k
u
k
e
r
u
u
d
u
f
q
g
c
v
w
n
z
a
f
e
u
n
z
k
j
l
j
z
c
j
r
m
c
d
c
h
h
p
j
g
m
t
t
n
d
r
r
p
a
m
g
y
r
t
w
s
l
m
s
w
a
s
x
t
i
u
s
v
l
w
i
x
f
q
p
x
m
s
l
d
r
v
n
a
d
z
l
p
e
h
k
j
k
z
j
z
g
m
e
k
o
k
m
p
t
w
v
v
q
v
l
y
z
s
m
c
m
e
r
s
z
c
j
f
w
z
b
p
w
s
p
l
u
p
w
k
d
t
z
a
n
g
j
p
v
a
s
c
r
g
a
r
g
i
n
u
r
c
e
i
i
r
j
p
z
y
c
x
r
j
c
i
t
n
j
u
r
u
a
x
g
g
x
w
c
k

200
tmp/2.txt Normal file
View File

@ -0,0 +1,200 @@
v
q
l
x
z
p
v
l
h
n
b
q
b
n
x
h
b
s
i
n
f
v
i
a
k
w
d
u
r
d
j
p
t
j
d
u
w
u
k
u
o
n
n
w
d
d
d
h
d
i
o
n
b
c
j
a
l
b
q
i
z
s
r
z
s
z
z
y
o
y
r
g
o
z
k
x
j
o
r
r
m
s
w
p
k
a
m
y
q
g
j
t
h
f
b
q
j
v
r
z
m
f
r
y
k
v
x
m
k
p
e
a
q
a
i
w
e
c
t
y
m
t
g
x
t
a
u
c
d
o
x
n
s
y
b
q
s
v
i
p
u
o
f
l
e
n
n
j
d
x
n
w
d
n
t
p
b
j
f
i
f
d
p
v
f
p
b
u
i
b
l
i
b
f
j
f
a
w
m
s
d
j
h
p
b
b
q
c
u
v
l
k
d
o
f
g
m
z
r
b

200
tmp/20.txt Normal file
View File

@ -0,0 +1,200 @@
e
x
r
h
g
g
s
v
s
a
g
b
t
d
r
m
x
p
c
k
q
n
d
n
s
r
a
b
g
u
v
t
a
r
z
s
p
g
e
f
j
f
x
p
t
n
t
m
v
h
l
k
t
q
k
x
y
o
k
h
j
h
d
r
x
n
q
l
q
w
l
b
p
z
u
h
n
n
h
w
r
i
m
e
a
t
n
v
d
c
m
l
d
i
y
z
g
m
z
i
g
o
u
k
f
u
h
d
m
x
g
y
t
e
m
n
b
x
m
d
p
z
r
y
w
u
x
s
s
v
o
d
d
e
z
p
t
j
t
d
t
m
a
e
e
l
h
n
m
g
d
z
r
y
o
f
p
a
k
w
m
p
j
l
c
o
u
k
t
c
q
u
d
a
b
o
w
z
z
i
v
f
s
b
h
b
j
o
v
v
h
z
s
p
d
l
n
y
h
e

200
tmp/21.txt Normal file
View File

@ -0,0 +1,200 @@
l
b
k
r
o
h
d
c
f
r
l
j
y
i
i
z
q
o
v
f
h
x
r
c
b
u
j
p
u
z
q
u
a
s
x
w
n
x
y
u
d
z
u
t
u
m
a
m
x
a
n
x
f
s
x
n
m
q
k
n
r
f
t
i
k
m
q
o
l
j
i
s
v
g
x
e
j
x
l
e
j
y
z
d
q
c
g
f
r
s
e
s
p
t
f
p
o
z
j
s
n
j
o
a
m
f
o
t
k
a
w
c
y
p
i
i
t
o
s
c
h
a
m
t
k
y
s
d
v
d
f
b
d
q
m
g
i
t
g
e
t
k
d
h
w
y
p
a
f
c
a
k
r
t
k
u
f
q
h
a
r
c
z
y
t
v
a
j
a
d
g
i
m
p
w
y
c
j
q
c
y
j
e
m
x
b
w
n
x
p
s
d
i
c
g
t
a
d
q
o

200
tmp/22.txt Normal file
View File

@ -0,0 +1,200 @@
j
c
b
a
n
c
s
x
b
s
w
h
s
y
i
f
w
t
z
q
l
l
q
b
w
f
s
y
c
e
m
z
c
p
f
m
p
y
g
y
w
u
s
w
k
z
w
n
a
s
q
s
x
d
c
s
i
f
x
z
b
t
i
i
p
l
n
a
c
s
a
o
j
v
n
p
b
f
t
c
y
v
g
t
s
g
s
w
k
q
l
g
g
t
v
a
i
l
b
v
l
c
a
n
n
d
k
t
a
e
h
p
b
q
m
q
c
v
q
u
s
z
m
i
h
c
h
a
l
x
g
x
d
v
c
w
q
l
t
u
q
t
t
b
g
l
b
u
o
z
y
d
f
r
c
f
r
a
i
n
b
n
x
h
w
h
k
a
g
p
h
t
j
o
m
m
y
s
a
d
c
l
f
g
b
a
u
n
x
z
j
j
t
z
s
u
p
f
p
t

200
tmp/23.txt Normal file
View File

@ -0,0 +1,200 @@
l
c
k
f
o
i
l
x
o
d
c
z
f
j
y
p
x
l
g
s
s
a
w
c
j
j
f
o
l
r
x
i
o
j
e
w
h
v
s
m
d
k
z
k
y
l
b
u
o
z
s
q
s
n
b
o
u
h
h
p
y
c
n
g
y
j
m
m
y
w
e
o
g
v
a
f
c
n
o
t
r
n
h
d
k
n
r
p
k
n
q
g
o
e
i
e
k
d
v
s
i
o
v
h
f
g
i
m
w
v
h
h
u
t
c
m
b
i
m
v
i
u
p
b
d
z
d
e
x
e
o
a
z
i
n
f
k
s
k
m
j
n
i
x
r
a
w
y
o
b
k
o
n
w
o
f
o
d
v
c
t
t
q
a
l
f
d
i
z
y
i
t
f
n
h
c
j
q
e
e
c
g
i
n
a
x
e
w
x
f
s
y
e
j
n
u
n
y
b
h

200
tmp/24.txt Normal file
View File

@ -0,0 +1,200 @@
m
d
o
o
y
g
q
a
h
q
a
c
u
s
n
s
y
d
g
c
b
l
o
l
a
o
p
h
c
f
j
q
z
k
q
b
s
d
y
h
i
f
u
v
r
w
x
f
l
n
n
t
c
t
f
h
b
t
w
k
t
w
g
g
p
m
x
l
t
k
j
o
x
t
e
n
u
z
n
u
t
c
c
u
e
q
g
m
o
e
j
i
v
o
y
u
i
d
w
h
n
d
n
d
m
c
r
k
m
o
z
y
c
z
f
f
c
d
c
a
w
z
p
i
r
s
m
q
f
b
s
b
u
s
v
b
n
e
b
j
t
e
p
u
k
m
z
v
n
k
z
f
t
d
i
o
w
w
g
f
q
a
b
l
s
n
d
w
w
h
z
z
o
k
q
e
j
a
q
k
k
w
y
c
x
o
h
m
o
t
m
h
w
h
h
j
y
x
b
r

200
tmp/25.txt Normal file
View File

@ -0,0 +1,200 @@
t
j
c
x
a
y
y
y
v
x
o
k
i
f
x
n
z
v
h
t
x
r
g
x
o
v
r
g
r
a
h
l
c
u
w
w
p
p
l
h
p
d
x
m
c
d
j
e
f
z
m
d
u
h
g
m
z
k
o
m
o
w
b
v
o
l
o
w
u
h
z
w
z
a
g
d
q
e
a
s
f
k
v
f
z
a
n
a
p
u
z
a
i
v
r
m
r
b
q
q
d
g
a
g
s
d
o
l
k
f
l
z
p
c
v
j
u
e
w
c
s
u
i
l
c
h
b
g
l
h
o
r
t
k
c
v
r
t
r
g
y
h
p
t
a
e
h
v
j
w
p
y
f
l
f
z
p
n
h
e
n
e
s
n
c
t
f
n
c
s
t
y
i
m
b
d
f
m
r
j
y
b
p
b
m
x
h
n
u
k
f
i
p
u
z
b
w
i
q
s

200
tmp/26.txt Normal file
View File

@ -0,0 +1,200 @@
x
u
b
y
o
r
s
g
z
t
e
c
f
j
z
o
a
t
p
p
d
e
y
u
b
q
c
k
k
m
h
t
q
b
i
b
r
o
z
w
e
k
w
k
o
u
t
m
z
z
v
l
i
z
j
d
p
s
y
i
v
a
j
z
a
h
j
i
r
z
h
h
z
t
k
o
q
l
y
i
a
p
n
b
r
o
w
l
q
l
b
y
z
s
z
j
r
h
q
t
m
g
d
x
f
f
o
o
a
o
u
v
g
d
k
a
i
c
u
b
s
o
k
z
k
h
q
u
l
t
x
c
a
m
e
v
j
q
g
s
y
v
w
c
s
d
x
y
t
n
e
n
i
b
g
y
x
d
q
x
h
h
i
j
q
i
z
s
b
h
b
q
h
p
u
p
f
n
u
s
q
j
g
k
e
v
n
i
s
t
i
c
y
i
h
v
t
c
s
w

200
tmp/3.txt Normal file
View File

@ -0,0 +1,200 @@
m
r
f
g
q
k
w
e
z
l
z
h
u
w
e
m
r
y
y
v
i
t
h
n
j
x
k
n
m
f
t
u
q
s
h
a
t
z
w
g
y
e
f
z
c
i
m
m
b
q
l
f
m
e
h
b
j
m
e
q
p
s
l
o
q
n
g
s
m
a
q
y
n
s
r
b
j
i
l
u
v
e
k
w
u
u
r
g
g
p
j
s
e
l
n
c
k
x
u
l
z
l
e
b
l
g
x
a
y
l
z
s
m
l
k
q
r
d
u
a
k
u
h
u
p
f
t
t
m
q
q
t
b
j
i
k
f
j
f
b
i
o
c
a
b
n
g
b
y
g
a
n
c
d
g
z
p
w
p
h
t
b
b
v
b
c
p
a
n
k
m
s
g
y
e
k
b
b
i
f
f
e
p
j
v
k
e
f
o
x
z
y
a
i
m
e
v
i
p
f

200
tmp/4.txt Normal file
View File

@ -0,0 +1,200 @@
v
o
v
y
z
w
j
o
l
m
h
m
n
y
q
i
f
l
f
r
h
b
c
y
e
m
e
r
q
c
w
f
k
o
e
t
o
m
k
d
t
e
c
e
l
c
g
x
t
e
e
a
h
v
b
j
q
w
b
c
k
l
w
f
w
i
r
q
e
h
g
y
l
g
g
b
z
v
l
y
j
v
r
v
y
h
p
s
v
u
x
m
z
u
d
s
z
f
k
r
f
c
a
k
l
r
l
q
h
d
e
s
j
s
x
h
b
x
p
m
f
o
h
t
z
a
b
x
c
r
l
o
t
p
k
r
g
p
a
o
r
c
w
z
i
i
v
a
w
q
i
d
m
l
h
o
v
t
o
r
g
u
x
w
u
q
u
e
n
v
l
m
z
q
c
v
e
t
c
x
m
h
r
b
e
d
h
d
g
u
d
z
v
k
g
d
n
j
v
y

200
tmp/5.txt Normal file
View File

@ -0,0 +1,200 @@
e
n
i
i
s
v
m
v
e
l
x
r
d
h
j
o
a
u
t
m
j
q
z
f
r
r
k
b
t
o
b
w
b
h
u
t
q
c
g
u
k
h
k
x
k
z
c
t
u
s
a
g
y
u
f
o
c
d
k
r
o
l
o
o
g
k
n
h
z
n
t
w
f
r
e
h
h
j
r
x
e
i
p
d
x
k
h
o
a
y
e
c
h
k
f
s
v
k
m
t
x
u
d
o
w
o
k
j
z
m
l
f
f
p
w
w
l
b
m
i
r
q
s
o
j
i
g
j
z
g
s
n
o
u
w
p
f
b
w
o
w
p
m
k
y
x
q
z
s
m
u
f
e
z
p
a
j
l
t
f
w
g
c
d
p
o
r
h
o
r
n
n
f
n
e
c
i
j
m
n
z
h
r
n
h
i
k
v
t
h
b
o
n
j
k
v
r
l
w
o

200
tmp/6.txt Normal file
View File

@ -0,0 +1,200 @@
q
k
k
x
d
y
p
p
p
d
w
h
c
x
i
d
d
v
b
v
p
n
b
j
g
p
w
t
d
q
o
t
m
o
n
m
g
b
y
y
s
x
s
h
j
e
t
p
w
a
j
a
t
q
z
l
u
v
h
r
d
i
l
v
a
j
r
t
u
d
z
q
e
g
u
s
i
l
m
b
x
g
u
y
h
y
s
u
a
i
f
t
y
u
g
m
t
p
u
b
a
k
v
m
z
m
f
h
l
y
q
q
f
g
z
r
r
k
q
p
h
o
k
a
f
a
t
g
k
m
v
n
l
c
g
l
d
e
m
f
u
j
t
p
n
z
p
q
h
b
e
j
l
w
o
k
p
e
y
a
z
b
v
w
a
g
f
h
s
r
p
s
u
r
a
b
j
a
h
m
a
t
x
e
i
w
i
e
v
g
m
c
d
x
j
n
w
q
s
e

200
tmp/7.txt Normal file
View File

@ -0,0 +1,200 @@
q
j
z
j
i
x
g
j
z
n
v
y
o
o
k
d
k
q
z
e
x
s
y
m
n
y
h
q
f
b
l
q
y
v
q
h
w
b
s
o
a
w
f
x
c
y
k
f
v
m
t
d
j
f
i
x
q
w
g
z
d
y
q
r
l
m
l
c
m
u
t
j
g
g
s
k
e
j
o
g
p
z
r
s
d
c
j
i
w
i
i
o
l
j
p
e
i
s
c
h
z
c
m
u
j
s
x
p
k
g
z
y
k
q
r
p
y
o
r
v
k
l
x
l
w
x
f
d
b
v
v
j
s
f
u
j
i
f
a
x
t
z
g
l
b
c
b
r
r
e
b
k
v
d
k
x
b
f
n
f
i
s
q
w
t
k
c
v
d
q
f
x
y
v
v
l
w
d
w
o
s
f
j
l
m
a
l
f
c
v
u
o
m
q
e
r
v
z
g
f

Some files were not shown because too many files have changed in this diff Show More