Esempi di sincronizzazione tra thread

This commit is contained in:
Fabio Scotto di Santolo
2020-05-10 11:53:01 +02:00
parent a80d64735b
commit 9b85eed528
9 changed files with 315 additions and 172 deletions

111
.gitignore vendored
View File

@@ -1,6 +1,92 @@
# Add any directories, files, or patterns you don't want to be tracked by version control
# Created by https://www.gitignore.io/api/Java
# Edit at https://www.gitignore.io/?templates=Java
# Created by https://www.gitignore.io/api/java,maven,intellij,sonar
# Edit at https://www.gitignore.io/?templates=java,maven,intellij,sonar
### Intellij ###
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
# User-specific stuff
.idea/**/workspace.xml
.idea/**/tasks.xml
.idea/**/usage.statistics.xml
.idea/**/dictionaries
.idea/**/shelf
# Generated files
.idea/**/contentModel.xml
# Sensitive or high-churn files
.idea/**/dataSources/
.idea/**/dataSources.ids
.idea/**/dataSources.local.xml
.idea/**/sqlDataSources.xml
.idea/**/dynamic.xml
.idea/**/uiDesigner.xml
.idea/**/dbnavigator.xml
# Gradle
.idea/**/gradle.xml
.idea/**/libraries
# Gradle and Maven with auto-import
# When using Gradle or Maven with auto-import, you should exclude module files,
# since they will be recreated, and may cause churn. Uncomment if using
# auto-import.
.idea/modules.xml
.idea/*.iml
.idea/modules
*.iml
*.ipr
# CMake
cmake-build-*/
# Mongo Explorer plugin
.idea/**/mongoSettings.xml
# File-based project format
*.iws
# IntelliJ
out/
# mpeltonen/sbt-idea plugin
.idea_modules/
# JIRA plugin
atlassian-ide-plugin.xml
# Cursive Clojure plugin
.idea/replstate.xml
# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
fabric.properties
# Editor-based Rest Client
.idea/httpRequests
# Android studio 3.1+ serialized cache file
.idea/caches/build_file_checksums.ser
### Intellij Patch ###
# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721
modules.xml
.idea/misc.xml
# Sonarlint plugin
.idea/**/sonarlint/
# SonarQube Plugin
.idea/**/sonarIssues.xml
# Markdown Navigator plugin
.idea/**/markdown-navigator.xml
.idea/**/markdown-navigator/
### Java ###
# Compiled class file
@@ -27,4 +113,21 @@
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
# End of https://www.gitignore.io/api/Java
### Maven ###
target/
pom.xml.tag
pom.xml.releaseBackup
pom.xml.versionsBackup
pom.xml.next
release.properties
dependency-reduced-pom.xml
buildNumber.properties
.mvn/timing.properties
.mvn/wrapper/maven-wrapper.jar
.flattened-pom.xml
### Sonar ###
#Sonar generated dir
/.sonar/
# End of https://www.gitignore.io/api/java,maven,intellij,sonar

167
.idea/workspace.xml generated
View File

@@ -1,167 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="BranchesTreeState">
<expand>
<path>
<item name="ROOT" type="e8cecc67:BranchNodeDescriptor" />
<item name="LOCAL_ROOT" type="e8cecc67:BranchNodeDescriptor" />
</path>
<path>
<item name="ROOT" type="e8cecc67:BranchNodeDescriptor" />
<item name="REMOTE_ROOT" type="e8cecc67:BranchNodeDescriptor" />
</path>
<path>
<item name="ROOT" type="e8cecc67:BranchNodeDescriptor" />
<item name="REMOTE_ROOT" type="e8cecc67:BranchNodeDescriptor" />
<item name="GROUP_NODE:origin" type="e8cecc67:BranchNodeDescriptor" />
</path>
</expand>
<select />
</component>
<component name="ChangeListManager">
<list default="true" id="7689427a-6b8c-43cf-a2b5-7eb7ae541ad3" name="Default Changelist" comment="">
<change beforePath="$PROJECT_DIR$/.classpath" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/sonarlint/issuestore/index.pb" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/sonarlint/issuestore/index.pb" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.project" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/.settings/org.eclipse.jdt.core.prefs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/.vscode/launch.json" beforeDir="false" />
</list>
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
<option name="LAST_RESOLUTION" value="IGNORE" />
</component>
<component name="CodeStyleSettingsInfer">
<option name="done" value="true" />
</component>
<component name="FileTemplateManagerImpl">
<option name="RECENT_TEMPLATES">
<list>
<option value="Class" />
</list>
</option>
</component>
<component name="Git.Settings">
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
</component>
<component name="ProjectCodeStyleSettingsMigration">
<option name="version" value="1" />
</component>
<component name="ProjectId" id="1XtW4Cv6Jj7Gvlhk7hHpikOtIsR" />
<component name="ProjectViewState">
<option name="hideEmptyMiddlePackages" value="true" />
<option name="showLibraryContents" value="true" />
</component>
<component name="PropertiesComponent">
<property name="RunOnceActivity.OpenProjectViewOnStart" value="true" />
<property name="RunOnceActivity.ShowReadmeOnStart" value="true" />
<property name="WebServerToolWindowFactoryState" value="false" />
<property name="aspect.path.notification.shown" value="true" />
<property name="last_opened_file_path" value="$PROJECT_DIR$" />
</component>
<component name="RunManager">
<configuration name="InnerClassDemo" type="Application" factoryName="Application" temporary="true" nameIsGenerated="true">
<option name="MAIN_CLASS_NAME" value="com.oracle.java8.associate.InnerClassDemo" />
<module name="OracleCertificationTest" />
<extension name="coverage">
<pattern>
<option name="PATTERN" value="com.oracle.java8.associate.*" />
<option name="ENABLED" value="true" />
</pattern>
</extension>
<method v="2">
<option name="Make" enabled="true" />
</method>
</configuration>
<recent_temporary>
<list>
<item itemvalue="Application.InnerClassDemo" />
</list>
</recent_temporary>
</component>
<component name="SvnConfiguration">
<configuration />
</component>
<component name="TaskManager">
<task active="true" id="Default" summary="Default task">
<changelist id="7689427a-6b8c-43cf-a2b5-7eb7ae541ad3" name="Default Changelist" comment="" />
<created>1581865677580</created>
<option name="number" value="Default" />
<option name="presentableId" value="Default" />
<updated>1581865677580</updated>
<workItem from="1581865678731" duration="45000" />
<workItem from="1588399470293" duration="828000" />
<workItem from="1588406335490" duration="577000" />
</task>
<servers />
</component>
<component name="TypeScriptGeneratedFilesManager">
<option name="version" value="2" />
</component>
<component name="Vcs.Log.Tabs.Properties">
<option name="TAB_STATES">
<map>
<entry key="MAIN">
<value>
<State />
</value>
</entry>
</map>
</option>
<option name="oldMeFiltersMigrated" value="true" />
</component>
<component name="WindowStateProjectService">
<state x="745" y="478" key="#com.intellij.ide.util.projectWizard.JdkChooserPanel.MyDialog" timestamp="1581865697666">
<screen x="0" y="23" width="1792" height="1097" />
</state>
<state x="745" y="478" key="#com.intellij.ide.util.projectWizard.JdkChooserPanel.MyDialog/0.23.1792.1097@0.23.1792.1097" timestamp="1581865697666" />
<state width="1750" height="675" key="GridCell.Tab.0.bottom" timestamp="1588406643415">
<screen x="0" y="23" width="1792" height="1097" />
</state>
<state width="1750" height="675" key="GridCell.Tab.0.bottom/0.23.1792.1097@0.23.1792.1097" timestamp="1588406643415" />
<state width="1750" height="675" key="GridCell.Tab.0.center" timestamp="1588406643415">
<screen x="0" y="23" width="1792" height="1097" />
</state>
<state width="1750" height="675" key="GridCell.Tab.0.center/0.23.1792.1097@0.23.1792.1097" timestamp="1588406643415" />
<state width="1750" height="675" key="GridCell.Tab.0.left" timestamp="1588406643414">
<screen x="0" y="23" width="1792" height="1097" />
</state>
<state width="1750" height="675" key="GridCell.Tab.0.left/0.23.1792.1097@0.23.1792.1097" timestamp="1588406643414" />
<state width="1750" height="675" key="GridCell.Tab.0.right" timestamp="1588406643415">
<screen x="0" y="23" width="1792" height="1097" />
</state>
<state width="1750" height="675" key="GridCell.Tab.0.right/0.23.1792.1097@0.23.1792.1097" timestamp="1588406643415" />
<state width="1750" height="675" key="GridCell.Tab.1.bottom" timestamp="1588406643416">
<screen x="0" y="23" width="1792" height="1097" />
</state>
<state width="1750" height="675" key="GridCell.Tab.1.bottom/0.23.1792.1097@0.23.1792.1097" timestamp="1588406643416" />
<state width="1750" height="675" key="GridCell.Tab.1.center" timestamp="1588406643416">
<screen x="0" y="23" width="1792" height="1097" />
</state>
<state width="1750" height="675" key="GridCell.Tab.1.center/0.23.1792.1097@0.23.1792.1097" timestamp="1588406643416" />
<state width="1750" height="675" key="GridCell.Tab.1.left" timestamp="1588406643415">
<screen x="0" y="23" width="1792" height="1097" />
</state>
<state width="1750" height="675" key="GridCell.Tab.1.left/0.23.1792.1097@0.23.1792.1097" timestamp="1588406643415" />
<state width="1750" height="675" key="GridCell.Tab.1.right" timestamp="1588406643416">
<screen x="0" y="23" width="1792" height="1097" />
</state>
<state width="1750" height="675" key="GridCell.Tab.1.right/0.23.1792.1097@0.23.1792.1097" timestamp="1588406643416" />
<state x="561" y="268" key="search.everywhere.popup" timestamp="1588401428428">
<screen x="0" y="23" width="1792" height="1097" />
</state>
<state x="561" y="268" key="search.everywhere.popup/0.23.1792.1097@0.23.1792.1097" timestamp="1588401428428" />
</component>
<component name="XDebuggerManager">
<breakpoint-manager>
<breakpoints>
<line-breakpoint enabled="true" type="java-line">
<url>file://$PROJECT_DIR$/src/com/oracle/java8/associate/InnerClassDemo.java</url>
<line>10</line>
<option name="timeStamp" value="2" />
</line-breakpoint>
</breakpoints>
</breakpoint-manager>
</component>
</project>

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager">
<output url="file://$MODULE_DIR$/bin" />
<output url="file://$MODULE_DIR$/out" />
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />

View File

@@ -0,0 +1,51 @@
package com.oracle.java8.professional;
import com.oracle.java8.professional.concurrency.BankAccount;
import com.oracle.java8.professional.concurrency.Data;
import com.oracle.java8.professional.concurrency.Receiver;
import com.oracle.java8.professional.concurrency.Sender;
public class ConcurrencyTest {
public static void main(String[] args) {
doBankAccoundDemo();
doSynchronizeThreadDemo();
}
private static void doBankAccoundDemo() {
BankAccount bankAccount = new BankAccount(1, 100);
Thread worker1 = new Thread(() -> {
System.out.printf("[Thread %s] read current balance = %d\n",
Thread.currentThread().getName(), bankAccount.getBalance());
bankAccount.deposit(10);
});
Thread worker2 = new Thread(() -> {
System.out.printf("[Thread %s] read current balance = %d\n",
Thread.currentThread().getName(), bankAccount.getBalance());
bankAccount.deposit(10000);
});
worker1.start();
worker2.start();
try {
worker1.join();
worker2.join();
System.out.println("Final balance is " + bankAccount.getBalance());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private static void doSynchronizeThreadDemo() {
Data data = new Data();
Thread sender = new Thread(new Sender(data));
Thread receiver = new Thread(new Receiver(data));
sender.start();
receiver.start();
}
}

View File

@@ -0,0 +1,19 @@
package com.oracle.java8.professional.concurrency;
public class BankAccount {
private long number;
private long balance;
public BankAccount(long number, long balance) {
this.number = number;
this.balance = balance;
}
public synchronized long getBalance() {
return balance;
}
public synchronized void deposit(long amout) {
balance += amout;
}
}

View File

@@ -0,0 +1,40 @@
package com.oracle.java8.professional.concurrency;
import java.util.logging.Level;
import java.util.logging.Logger;
public class Data {
private String packet;
private boolean transfer = true;
public synchronized void send(String packet) {
while (!transfer) {
try {
wait();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
Logger.getAnonymousLogger().log(Level.SEVERE, "Interrupted error", e);
}
}
transfer = false;
this.packet = packet;
notifyAll();
}
public synchronized String receive() {
while (transfer) {
try {
wait();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
Logger.getAnonymousLogger().log(Level.SEVERE, "Interrupted error", e);
}
}
transfer = true;
notifyAll();
return packet;
}
}

View File

@@ -0,0 +1,29 @@
package com.oracle.java8.professional.concurrency;
public class PingPong extends Thread {
private String word;
private int delay;
public PingPong(String whatToSay, int delayTime) {
this.word = whatToSay;
this.delay = delayTime;
}
@Override
public void run() {
try {
for (;;) {
System.out.println(word + " ");
Thread.sleep(delay);
}
} catch (InterruptedException e) {
return;
}
}
public static void main(String[] args) {
System.out.println(Thread.currentThread().getName());
new PingPong("ping", 33).start();
new PingPong("PONG", 100).start();
}
}

View File

@@ -0,0 +1,31 @@
package com.oracle.java8.professional.concurrency;
import java.util.concurrent.ThreadLocalRandom;
import java.util.logging.Level;
import java.util.logging.Logger;
public class Receiver implements Runnable {
private Data load;
public Receiver(Data data) {
this.load = data;
}
public void run() {
for (String receivedMessage = load.receive();
!"End".equals(receivedMessage);
receivedMessage = load.receive()) {
System.out.println(receivedMessage);
// ...
try {
Thread.sleep(ThreadLocalRandom.current().nextInt(1000, 5000));
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
Logger.getAnonymousLogger().log(Level.SEVERE, "Interrupted error", e);
}
}
}
}

View File

@@ -0,0 +1,37 @@
package com.oracle.java8.professional.concurrency;
import java.util.concurrent.ThreadLocalRandom;
import java.util.logging.Level;
import java.util.logging.Logger;
public class Sender implements Runnable {
private Data data;
public Sender(Data data) {
this.data = data;
}
@Override
public void run() {
String packets[] = {
"First packet",
"Second packet",
"Third packet",
"Fourth packet",
"End"
};
for (String packet : packets) {
data.send(packet);
// Thread.sleep() to mimic heavy server-side processing
try {
Thread.sleep(ThreadLocalRandom.current().nextInt(1000, 5000));
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
Logger.getAnonymousLogger().log(Level.SEVERE, "Interrupted error", e);
}
}
}
}