concurrent_study
This commit is contained in:
commit
518a399355
|
@ -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
|
|
@ -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
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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");
|
||||||
|
}
|
||||||
|
}
|
|
@ -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());
|
||||||
|
}
|
||||||
|
}
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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));
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -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");
|
||||||
|
}
|
||||||
|
}
|
|
@ -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
|
||||||
|
* */
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -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) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -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 +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -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();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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());
|
||||||
|
}
|
||||||
|
}
|
|
@ -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());
|
||||||
|
}
|
||||||
|
}
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -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("结束");
|
||||||
|
}
|
||||||
|
}
|
|
@ -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());
|
||||||
|
}
|
||||||
|
}
|
|
@ -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 {
|
||||||
|
|
||||||
|
}
|
|
@ -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 {
|
||||||
|
|
||||||
|
}
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -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上所有等待线程 断点
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -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>
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
Loading…
Reference in New Issue