Fin du rendu

master
Elliott LE GUEHENNEC 2 years ago
parent 274abb7775
commit 47fe4bec9d

@ -21,7 +21,13 @@ Ici, la `ArrayBlockingQueue` devient le moniteur, car elle gère elle-même l'ac
## 3. Fin de programme
### A.
Ca n'est pas une bonne solution, car s'il y a plus de producteurs que de consommateurs, les producteurs s'arrêtent de produire alors qu'il reste encore des consommateurs, bloquant ainsi des consommateurs qui n'ont pas acheté toutes les pâtisseries qu'ils voulaient.
### C.
L'inconvénient est que le main doit directement interagir avec la boulangerie comme s'il était un producteur particulier.
Si on essaie d'insérer un gâteau empoisonné alors que la queue est déjà pleine, cela peut causer des soucis.
## Code
@ -33,6 +39,7 @@ public class Patisserie {
}
public class Gateau extends Patisserie {
public static final Gateau GATEAU_EMPOISONNE = new Gateau();
public Gateau() {
}
@ -101,6 +108,29 @@ public class Patissier implements Runnable {
}
}
public class PatissierSuicidal extends Patissier {
public AtomicBoolean shouldRun = new AtomicBoolean(true);
public PatissierSuicidal(Boulangerie b) {
super(b);
}
@Override
public void run() {
while(shouldRun.get()) {
if(!local.depose(new Patisserie())){
shouldRun.set(false);
}
System.out.println("J'ai produit ma patisserie");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
break;
}
}
}
}
public class Boulangerie {
private final ArrayList<Patisserie> sweets = new ArrayList<>();
@ -118,33 +148,36 @@ public class Boulangerie {
}
public void getStock() {
// TODO implement here
return sweets.size();
}
}
public class BoulangerieThreadSafe extends Boulangerie{
private final BlockingQueue<Patisserie> sweets = new ArrayBlockingQueue<Patisserie>(50);
private final BlockingQueue<Patisserie> sweets = new ArrayBlockingQueue<Patisserie>(10);
@Override
public void depose(Patisserie p) {
public boolean depose(Patisserie p) {
try{
if(sweets.remainingCapacity() <= 0) return false;
sweets.put(p);
}catch(InterruptedException ignored){}
}catch(InterruptedException ignored){return false;}
return true;
}
@Override
public Patisserie achete() {
try{return sweets.take();} catch (InterruptedException e) {}
try{return sweets.take();} catch (InterruptedException ignored) {}
return null;
}
@Override
public void getStock() {
// TODO implement here
public int getStock() {
return sweets.size();
}
}
public class ThreadWeaver {
private final List<Runnable> runners = new ArrayList<Runnable>();
private final List<Thread> managed = new ArrayList<Thread>();
@ -235,4 +268,43 @@ public class Main2 {
tw.recover(100L);
}
}
public class Main3A {
public static void main(String[] args) {
ThreadWeaver tw = new ThreadWeaver();
Boulangerie b = new BoulangerieThreadSafe();
Patissier p = new Patissier(b);
tw.addRunners(p, new LimitedClient(b));
tw.weave();
tw.run();
try{
Thread.sleep(2000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
p.shouldRun.set(false);
tw.recover();
}
}
public class Main3B {
public static void main(String[] args) {
ThreadWeaver tw = new ThreadWeaver();
Boulangerie b = new BoulangerieThreadSafe();
Patissier p = new Patissier(b);
Client c1 = new Client(b);
tw.addRunners(p, c1);
tw.weave();
tw.run();
try{
Thread.sleep(2000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
b.depose(Gateau.GATEAU_EMPOISONNE);
tw.recover();
}
}
```

@ -0,0 +1,665 @@
<!DOCTYPE html>
<html>
<head>
<title>rendu.md</title>
<meta http-equiv="Content-type" content="text/html;charset=UTF-8">
<style>
/* https://github.com/microsoft/vscode/blob/master/extensions/markdown-language-features/media/markdown.css */
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
body {
font-family: var(--vscode-markdown-font-family, -apple-system, BlinkMacSystemFont, "Segoe WPC", "Segoe UI", "Ubuntu", "Droid Sans", sans-serif);
font-size: var(--vscode-markdown-font-size, 14px);
padding: 0 26px;
line-height: var(--vscode-markdown-line-height, 22px);
word-wrap: break-word;
}
#code-csp-warning {
position: fixed;
top: 0;
right: 0;
color: white;
margin: 16px;
text-align: center;
font-size: 12px;
font-family: sans-serif;
background-color:#444444;
cursor: pointer;
padding: 6px;
box-shadow: 1px 1px 1px rgba(0,0,0,.25);
}
#code-csp-warning:hover {
text-decoration: none;
background-color:#007acc;
box-shadow: 2px 2px 2px rgba(0,0,0,.25);
}
body.scrollBeyondLastLine {
margin-bottom: calc(100vh - 22px);
}
body.showEditorSelection .code-line {
position: relative;
}
body.showEditorSelection .code-active-line:before,
body.showEditorSelection .code-line:hover:before {
content: "";
display: block;
position: absolute;
top: 0;
left: -12px;
height: 100%;
}
body.showEditorSelection li.code-active-line:before,
body.showEditorSelection li.code-line:hover:before {
left: -30px;
}
.vscode-light.showEditorSelection .code-active-line:before {
border-left: 3px solid rgba(0, 0, 0, 0.15);
}
.vscode-light.showEditorSelection .code-line:hover:before {
border-left: 3px solid rgba(0, 0, 0, 0.40);
}
.vscode-light.showEditorSelection .code-line .code-line:hover:before {
border-left: none;
}
.vscode-dark.showEditorSelection .code-active-line:before {
border-left: 3px solid rgba(255, 255, 255, 0.4);
}
.vscode-dark.showEditorSelection .code-line:hover:before {
border-left: 3px solid rgba(255, 255, 255, 0.60);
}
.vscode-dark.showEditorSelection .code-line .code-line:hover:before {
border-left: none;
}
.vscode-high-contrast.showEditorSelection .code-active-line:before {
border-left: 3px solid rgba(255, 160, 0, 0.7);
}
.vscode-high-contrast.showEditorSelection .code-line:hover:before {
border-left: 3px solid rgba(255, 160, 0, 1);
}
.vscode-high-contrast.showEditorSelection .code-line .code-line:hover:before {
border-left: none;
}
img {
max-width: 100%;
max-height: 100%;
}
a {
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
a:focus,
input:focus,
select:focus,
textarea:focus {
outline: 1px solid -webkit-focus-ring-color;
outline-offset: -1px;
}
hr {
border: 0;
height: 2px;
border-bottom: 2px solid;
}
h1 {
padding-bottom: 0.3em;
line-height: 1.2;
border-bottom-width: 1px;
border-bottom-style: solid;
}
h1, h2, h3 {
font-weight: normal;
}
table {
border-collapse: collapse;
}
table > thead > tr > th {
text-align: left;
border-bottom: 1px solid;
}
table > thead > tr > th,
table > thead > tr > td,
table > tbody > tr > th,
table > tbody > tr > td {
padding: 5px 10px;
}
table > tbody > tr + tr > td {
border-top: 1px solid;
}
blockquote {
margin: 0 7px 0 5px;
padding: 0 16px 0 10px;
border-left-width: 5px;
border-left-style: solid;
}
code {
font-family: Menlo, Monaco, Consolas, "Droid Sans Mono", "Courier New", monospace, "Droid Sans Fallback";
font-size: 1em;
line-height: 1.357em;
}
body.wordWrap pre {
white-space: pre-wrap;
}
pre:not(.hljs),
pre.hljs code > div {
padding: 16px;
border-radius: 3px;
overflow: auto;
}
pre code {
color: var(--vscode-editor-foreground);
tab-size: 4;
}
/** Theming */
.vscode-light pre {
background-color: rgba(220, 220, 220, 0.4);
}
.vscode-dark pre {
background-color: rgba(10, 10, 10, 0.4);
}
.vscode-high-contrast pre {
background-color: rgb(0, 0, 0);
}
.vscode-high-contrast h1 {
border-color: rgb(0, 0, 0);
}
.vscode-light table > thead > tr > th {
border-color: rgba(0, 0, 0, 0.69);
}
.vscode-dark table > thead > tr > th {
border-color: rgba(255, 255, 255, 0.69);
}
.vscode-light h1,
.vscode-light hr,
.vscode-light table > tbody > tr + tr > td {
border-color: rgba(0, 0, 0, 0.18);
}
.vscode-dark h1,
.vscode-dark hr,
.vscode-dark table > tbody > tr + tr > td {
border-color: rgba(255, 255, 255, 0.18);
}
</style>
<style>
/* Tomorrow Theme */
/* http://jmblog.github.com/color-themes-for-google-code-highlightjs */
/* Original theme - https://github.com/chriskempson/tomorrow-theme */
/* Tomorrow Comment */
.hljs-comment,
.hljs-quote {
color: #8e908c;
}
/* Tomorrow Red */
.hljs-variable,
.hljs-template-variable,
.hljs-tag,
.hljs-name,
.hljs-selector-id,
.hljs-selector-class,
.hljs-regexp,
.hljs-deletion {
color: #c82829;
}
/* Tomorrow Orange */
.hljs-number,
.hljs-built_in,
.hljs-builtin-name,
.hljs-literal,
.hljs-type,
.hljs-params,
.hljs-meta,
.hljs-link {
color: #f5871f;
}
/* Tomorrow Yellow */
.hljs-attribute {
color: #eab700;
}
/* Tomorrow Green */
.hljs-string,
.hljs-symbol,
.hljs-bullet,
.hljs-addition {
color: #718c00;
}
/* Tomorrow Blue */
.hljs-title,
.hljs-section {
color: #4271ae;
}
/* Tomorrow Purple */
.hljs-keyword,
.hljs-selector-tag {
color: #8959a8;
}
.hljs {
display: block;
overflow-x: auto;
color: #4d4d4c;
padding: 0.5em;
}
.hljs-emphasis {
font-style: italic;
}
.hljs-strong {
font-weight: bold;
}
</style>
<style>
/*
* Markdown PDF CSS
*/
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe WPC", "Segoe UI", "Ubuntu", "Droid Sans", sans-serif, "Meiryo";
padding: 0 12px;
}
pre {
background-color: #f8f8f8;
border: 1px solid #cccccc;
border-radius: 3px;
overflow-x: auto;
white-space: pre-wrap;
overflow-wrap: break-word;
}
pre:not(.hljs) {
padding: 23px;
line-height: 19px;
}
blockquote {
background: rgba(127, 127, 127, 0.1);
border-color: rgba(0, 122, 204, 0.5);
}
.emoji {
height: 1.4em;
}
code {
font-size: 14px;
line-height: 19px;
}
/* for inline code */
:not(pre):not(.hljs) > code {
color: #C9AE75; /* Change the old color so it seems less like an error */
font-size: inherit;
}
/* Page Break : use <div class="page"/> to insert page break
-------------------------------------------------------- */
.page {
page-break-after: always;
}
</style>
<script src="https://unpkg.com/mermaid/dist/mermaid.min.js"></script>
</head>
<body>
<script>
mermaid.initialize({
startOnLoad: true,
theme: document.body.classList.contains('vscode-dark') || document.body.classList.contains('vscode-high-contrast')
? 'dark'
: 'default'
});
</script>
<h1 id="tp2---syst%C3%A8me">TP2 - Système</h1>
<p>Elliott LE GUEHENNEC -- Yorick GEOFFRE</p>
<h2 id="1-simulation-dune-patisserie">1. Simulation d'une patisserie</h2>
<h3 id="a">A.</h3>
<p>Le patron lecteur/rédacteur présente le problème suivant : lorsqu'un lecteur lit la ressource, il la bloque et les rédacteurs ne peuvent pas la modifier. Or, dans notre configuration, il se peut que le <code>Client</code> doive attendre alors qu'il essaie d'obtenir sa <code>Patisserie</code>, mais il serait quand même en train de lire la file d'attente, empêchant ainsi le <code>Patissier</code> de réapprovisioner la file; c'est un deadlock.</p>
<h3 id="b">B.</h3>
<p>L'exclusion mutuelle se produit lorsqu'un <code>Client</code> veut acheter une <code>Patisserie</code> alors qu'aucune n'est disponible. Lorsque cela se produit, la <code>Boulangerie</code> bloque le thread en attendant qu'un <code>Patissier</code> dépose une <code>Patisserie</code> dans la boulangerie, débloquant ainsi la demande du client. La <code>Boulangerie</code> débloque le thread correspondant et retourne la <code>Patisserie</code> désirée au client.</p>
<p><img src="file:///home/UCA/elleguehen/pm/sys/Eclair/docs/s1.svg" alt=""></p>
<p>La <code>Boulangerie</code> est donc le moniteur dans ce modèle, on l'utilise pour synchroniser toutes les opérations des <code>Client</code>, des <code>Patissier</code>, et la file d'attente.</p>
<p>Pour lancer des threads, on a créé une class ThreadWeaver. On peut lui faire passer des <code>Runnable</code> avec <code>addRunners()</code>, puis on leur assigne un thread chacun avec <code>weave()</code>, avant de les lancer avec <code>run()</code>. Avec <code>recover()</code>, on attend que tous les threads se soient terminés, et avec <code>termina()</code>, on interrompt tous les threads restants en affichant une erreur.</p>
<h2 id="2-simulation-dune-patisserie-avec-collection-threadsafe">2. Simulation d'une patisserie avec collection ThreadSafe</h2>
<p>Ici, la <code>ArrayBlockingQueue</code> devient le moniteur, car elle gère elle-même l'accès par exclusion mutuelle. Le client sera bloqué par la file, et attendra tant qu'il n'aura pas son code grâce à <code>ArrayBlockingQueue.take();</code>.</p>
<h2 id="3-fin-de-programme">3. Fin de programme</h2>
<h3 id="a">A.</h3>
<p>Ca n'est pas une bonne solution, car s'il y a plus de producteurs que de consommateurs, les producteurs s'arrêtent de produire alors qu'il reste encore des consommateurs, bloquant ainsi des consommateurs qui n'ont pas acheté toutes les pâtisseries qu'ils voulaient.</p>
<h3 id="c">C.</h3>
<p>L'inconvénient est que le main doit directement interagir avec la boulangerie comme s'il était un producteur particulier.</p>
<p>Si on essaie d'insérer un gâteau empoisonné alors que la queue est déjà pleine, cela peut causer des soucis.</p>
<h2 id="code">Code</h2>
<pre class="hljs"><code><div><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Patisserie</span> </span>{
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">Patisserie</span><span class="hljs-params">()</span> </span>{
}
}
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Gateau</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Patisserie</span> </span>{
<span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> Gateau GATEAU_EMPOISONNE = <span class="hljs-keyword">new</span> Gateau();
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">Gateau</span><span class="hljs-params">()</span> </span>{
}
}
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Client</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">Runnable</span> </span>{
<span class="hljs-keyword">protected</span> <span class="hljs-keyword">final</span> Boulangerie local;
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">Client</span><span class="hljs-params">(Boulangerie b)</span> </span>{
local = b;
}
<span class="hljs-meta">@Override</span>
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">run</span><span class="hljs-params">()</span> </span>{
<span class="hljs-keyword">while</span>(<span class="hljs-keyword">true</span>) {
local.achete();
System.out.println(<span class="hljs-string">"J'ai acheté ma patisserie"</span>);
<span class="hljs-keyword">try</span> {
Thread.sleep(<span class="hljs-number">80</span>);
} <span class="hljs-keyword">catch</span> (InterruptedException e) {
<span class="hljs-keyword">break</span>;
}
}
}
}
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">LimitedClient</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Client</span></span>{
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">LimitedClient</span><span class="hljs-params">(Boulangerie b)</span> </span>{
<span class="hljs-keyword">super</span>(b);
}
<span class="hljs-meta">@Override</span>
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">run</span><span class="hljs-params">()</span> </span>{
<span class="hljs-keyword">while</span>(<span class="hljs-keyword">true</span>) {
local.achete();
System.out.println(<span class="hljs-string">"J'ai acheté ma patisserie - Limited"</span>);
<span class="hljs-keyword">try</span> {
Thread.sleep(<span class="hljs-number">80</span>);
} <span class="hljs-keyword">catch</span> (InterruptedException e) {
<span class="hljs-keyword">break</span>;
}
}
}
}
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Patissier</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">Runnable</span> </span>{
<span class="hljs-keyword">public</span> AtomicBoolean shouldRun = <span class="hljs-keyword">new</span> AtomicBoolean(<span class="hljs-keyword">true</span>);
<span class="hljs-keyword">private</span> <span class="hljs-keyword">final</span> Boulangerie local;
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">Patissier</span><span class="hljs-params">(Boulangerie b)</span> </span>{
local = b;
}
<span class="hljs-meta">@Override</span>
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">run</span><span class="hljs-params">()</span> </span>{
<span class="hljs-keyword">while</span>(shouldRun.get()) {
local.depose(<span class="hljs-keyword">new</span> Patisserie());
System.out.println(<span class="hljs-string">"J'ai produit ma patisserie"</span>);
<span class="hljs-keyword">try</span> {
Thread.sleep(<span class="hljs-number">100</span>);
} <span class="hljs-keyword">catch</span> (InterruptedException e) {
<span class="hljs-keyword">break</span>;
}
}
}
}
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">PatissierSuicidal</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Patissier</span> </span>{
<span class="hljs-keyword">public</span> AtomicBoolean shouldRun = <span class="hljs-keyword">new</span> AtomicBoolean(<span class="hljs-keyword">true</span>);
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">PatissierSuicidal</span><span class="hljs-params">(Boulangerie b)</span> </span>{
<span class="hljs-keyword">super</span>(b);
}
<span class="hljs-meta">@Override</span>
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">run</span><span class="hljs-params">()</span> </span>{
<span class="hljs-keyword">while</span>(shouldRun.get()) {
<span class="hljs-keyword">if</span>(!local.depose(<span class="hljs-keyword">new</span> Patisserie())){
shouldRun.set(<span class="hljs-keyword">false</span>);
}
System.out.println(<span class="hljs-string">"J'ai produit ma patisserie"</span>);
<span class="hljs-keyword">try</span> {
Thread.sleep(<span class="hljs-number">100</span>);
} <span class="hljs-keyword">catch</span> (InterruptedException e) {
<span class="hljs-keyword">break</span>;
}
}
}
}
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Boulangerie</span> </span>{
<span class="hljs-keyword">private</span> <span class="hljs-keyword">final</span> ArrayList&lt;Patisserie&gt; sweets = <span class="hljs-keyword">new</span> ArrayList&lt;&gt;();
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">synchronized</span> <span class="hljs-keyword">void</span> <span class="hljs-title">depose</span><span class="hljs-params">(Patisserie p)</span> </span>{
<span class="hljs-keyword">this</span>.notify();
sweets.add(p);
}
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">synchronized</span> Patisserie <span class="hljs-title">achete</span><span class="hljs-params">()</span> </span>{
<span class="hljs-keyword">while</span>(sweets.size() == <span class="hljs-number">0</span>) {
<span class="hljs-keyword">try</span> {<span class="hljs-keyword">this</span>.wait();} <span class="hljs-keyword">catch</span> (InterruptedException ignored) {}}
Patisserie pat = sweets.get(<span class="hljs-number">0</span>);
sweets.remove(pat);
<span class="hljs-keyword">return</span> pat;
}
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">getStock</span><span class="hljs-params">()</span> </span>{
<span class="hljs-keyword">return</span> sweets.size();
}
}
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">BoulangerieThreadSafe</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Boulangerie</span></span>{
<span class="hljs-keyword">private</span> <span class="hljs-keyword">final</span> BlockingQueue&lt;Patisserie&gt; sweets = <span class="hljs-keyword">new</span> ArrayBlockingQueue&lt;Patisserie&gt;(<span class="hljs-number">10</span>);
<span class="hljs-meta">@Override</span>
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">boolean</span> <span class="hljs-title">depose</span><span class="hljs-params">(Patisserie p)</span> </span>{
<span class="hljs-keyword">try</span>{
<span class="hljs-keyword">if</span>(sweets.remainingCapacity() &lt;= <span class="hljs-number">0</span>) <span class="hljs-keyword">return</span> <span class="hljs-keyword">false</span>;
sweets.put(p);
}<span class="hljs-keyword">catch</span>(InterruptedException ignored){<span class="hljs-keyword">return</span> <span class="hljs-keyword">false</span>;}
<span class="hljs-keyword">return</span> <span class="hljs-keyword">true</span>;
}
<span class="hljs-meta">@Override</span>
<span class="hljs-function"><span class="hljs-keyword">public</span> Patisserie <span class="hljs-title">achete</span><span class="hljs-params">()</span> </span>{
<span class="hljs-keyword">try</span>{<span class="hljs-keyword">return</span> sweets.take();} <span class="hljs-keyword">catch</span> (InterruptedException ignored) {}
<span class="hljs-keyword">return</span> <span class="hljs-keyword">null</span>;
}
<span class="hljs-meta">@Override</span>
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">int</span> <span class="hljs-title">getStock</span><span class="hljs-params">()</span> </span>{
<span class="hljs-keyword">return</span> sweets.size();
}
}
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ThreadWeaver</span> </span>{
<span class="hljs-keyword">private</span> <span class="hljs-keyword">final</span> List&lt;Runnable&gt; runners = <span class="hljs-keyword">new</span> ArrayList&lt;Runnable&gt;();
<span class="hljs-keyword">private</span> <span class="hljs-keyword">final</span> List&lt;Thread&gt; managed = <span class="hljs-keyword">new</span> ArrayList&lt;Thread&gt;();
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">addRunners</span><span class="hljs-params">(Runnable... addedRunners)</span></span>{
runners.addAll(Arrays.stream(addedRunners).toList());
}
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">weave</span><span class="hljs-params">()</span></span>{
<span class="hljs-keyword">for</span>(Runnable r: runners){
managed.add(<span class="hljs-keyword">new</span> Thread(r));
}
}
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">run</span><span class="hljs-params">()</span></span>{
<span class="hljs-keyword">for</span>(Thread t : managed){
t.start();
}
}
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">recover</span><span class="hljs-params">()</span></span>{
<span class="hljs-keyword">for</span>(Thread t : managed){
<span class="hljs-keyword">try</span> {
t.join();
}<span class="hljs-keyword">catch</span>(InterruptedException ie){
System.out.println(ie.getMessage());
}
}
termina();
}
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">recover</span><span class="hljs-params">(Long timeout)</span></span>{
<span class="hljs-keyword">for</span>(Thread t : managed){
<span class="hljs-keyword">try</span> {
t.join(timeout);
}<span class="hljs-keyword">catch</span>(InterruptedException ie){
System.out.println(ie.getMessage());
}
}
termina();
}
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">termina</span><span class="hljs-params">()</span></span>{
<span class="hljs-keyword">for</span>(Thread t : managed){
<span class="hljs-keyword">if</span>(t.isAlive()) {
System.out.println(<span class="hljs-string">"Thread "</span> + t.getName() + <span class="hljs-string">" has not stopped being cleaned up"</span>);
t.interrupt();
}
}
managed.clear();
runners.clear();
}
}
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Main</span> </span>{
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">main</span><span class="hljs-params">(String[] args)</span> </span>{
ThreadWeaver tw = <span class="hljs-keyword">new</span> ThreadWeaver();
Boulangerie b = <span class="hljs-keyword">new</span> Boulangerie();
Patissier p = <span class="hljs-keyword">new</span> Patissier(b);
tw.addRunners(p, <span class="hljs-keyword">new</span> Client(b));
tw.weave();
tw.run();
<span class="hljs-keyword">try</span>{
Thread.sleep(<span class="hljs-number">2000</span>);
} <span class="hljs-keyword">catch</span> (InterruptedException e) {
<span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> RuntimeException(e);
}
p.shouldRun.set(<span class="hljs-keyword">false</span>);
tw.recover(<span class="hljs-number">100L</span>);
}
}
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Main2</span> </span>{
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">main</span><span class="hljs-params">(String[] args)</span> </span>{
ThreadWeaver tw = <span class="hljs-keyword">new</span> ThreadWeaver();
Boulangerie b = <span class="hljs-keyword">new</span> BoulangerieThreadSafe();
Patissier p = <span class="hljs-keyword">new</span> Patissier(b);
tw.addRunners(p, <span class="hljs-keyword">new</span> Client(b));
tw.weave();
tw.run();
<span class="hljs-keyword">try</span>{
Thread.sleep(<span class="hljs-number">2000</span>);
} <span class="hljs-keyword">catch</span> (InterruptedException e) {
<span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> RuntimeException(e);
}
p.shouldRun.set(<span class="hljs-keyword">false</span>);
tw.recover(<span class="hljs-number">100L</span>);
}
}
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Main3A</span> </span>{
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">main</span><span class="hljs-params">(String[] args)</span> </span>{
ThreadWeaver tw = <span class="hljs-keyword">new</span> ThreadWeaver();
Boulangerie b = <span class="hljs-keyword">new</span> BoulangerieThreadSafe();
Patissier p = <span class="hljs-keyword">new</span> Patissier(b);
tw.addRunners(p, <span class="hljs-keyword">new</span> LimitedClient(b));
tw.weave();
tw.run();
<span class="hljs-keyword">try</span>{
Thread.sleep(<span class="hljs-number">2000</span>);
} <span class="hljs-keyword">catch</span> (InterruptedException e) {
<span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> RuntimeException(e);
}
p.shouldRun.set(<span class="hljs-keyword">false</span>);
tw.recover();
}
}
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Main3B</span> </span>{
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">main</span><span class="hljs-params">(String[] args)</span> </span>{
ThreadWeaver tw = <span class="hljs-keyword">new</span> ThreadWeaver();
Boulangerie b = <span class="hljs-keyword">new</span> BoulangerieThreadSafe();
Patissier p = <span class="hljs-keyword">new</span> Patissier(b);
Client c1 = <span class="hljs-keyword">new</span> Client(b);
tw.addRunners(p, c1);
tw.weave();
tw.run();
<span class="hljs-keyword">try</span>{
Thread.sleep(<span class="hljs-number">2000</span>);
} <span class="hljs-keyword">catch</span> (InterruptedException e) {
<span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> RuntimeException(e);
}
b.depose(Gateau.GATEAU_EMPOISONNE);
tw.recover();
}
}
</div></code></pre>
</body>
</html>
Loading…
Cancel
Save