Skip to content

Commit 541e1c0

Browse files
added task description (#1)
1 parent b748f1b commit 541e1c0

8 files changed

Lines changed: 130 additions & 22 deletions

File tree

README.md

Lines changed: 62 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,62 @@
1-
# jv-homework-template
1+
# Decrease counter
2+
3+
We wrote multi-threaded code that decreases the value of the `Counter` object.
4+
In `main()` method, 20 threads are created that accept the same `Counter` object.
5+
The task of each thread is to decrease the value of the `counter` by 1.
6+
7+
The original `counter` value is 20, so we should expect 0 in the end.
8+
9+
We are logging the value before and after each decrement, and now we see that the results are hardly consistent.
10+
11+
```
12+
INFO core.basesyntax.Counter:16 Before decrementing, Thread # 15, counter value 20
13+
INFO core.basesyntax.Counter:16 Before decrementing, Thread # 8, counter value 20
14+
INFO core.basesyntax.Counter:16 Before decrementing, Thread # 12, counter value 20
15+
INFO core.basesyntax.Counter:16 Before decrementing, Thread # 18, counter value 20
16+
INFO core.basesyntax.Counter:16 Before decrementing, Thread # 14, counter value 20
17+
INFO core.basesyntax.Counter:16 Before decrementing, Thread # 5, counter value 20
18+
INFO core.basesyntax.Counter:16 Before decrementing, Thread # 7, counter value 20
19+
INFO core.basesyntax.Counter:16 Before decrementing, Thread # 9, counter value 20
20+
INFO core.basesyntax.Counter:16 Before decrementing, Thread # 11, counter value 20
21+
INFO core.basesyntax.Counter:16 Before decrementing, Thread # 3, counter value 20
22+
INFO core.basesyntax.Counter:16 Before decrementing, Thread # 6, counter value 20
23+
INFO core.basesyntax.Counter:16 Before decrementing, Thread # 17, counter value 20
24+
INFO core.basesyntax.Counter:16 Before decrementing, Thread # 2, counter value 20
25+
INFO core.basesyntax.Counter:16 Before decrementing, Thread # 10, counter value 20
26+
INFO core.basesyntax.Counter:16 Before decrementing, Thread # 19, counter value 20
27+
INFO core.basesyntax.Counter:16 Before decrementing, Thread # 20, counter value 20
28+
INFO core.basesyntax.Counter:16 Before decrementing, Thread # 16, counter value 20
29+
INFO core.basesyntax.Counter:16 Before decrementing, Thread # 13, counter value 20
30+
INFO core.basesyntax.Counter:19 After decrementing, Thread # 7, counter value 12
31+
INFO core.basesyntax.Counter:16 Before decrementing, Thread # 1, counter value 20
32+
INFO core.basesyntax.Counter:19 After decrementing, Thread # 3, counter value 16
33+
INFO core.basesyntax.Counter:19 After decrementing, Thread # 20, counter value 10
34+
INFO core.basesyntax.Counter:19 After decrementing, Thread # 19, counter value 9
35+
INFO core.basesyntax.Counter:19 After decrementing, Thread # 5, counter value 17
36+
INFO core.basesyntax.Counter:19 After decrementing, Thread # 2, counter value 12
37+
INFO core.basesyntax.Counter:19 After decrementing, Thread # 8, counter value 18
38+
INFO core.basesyntax.Counter:19 After decrementing, Thread # 9, counter value 18
39+
INFO core.basesyntax.Counter:19 After decrementing, Thread # 14, counter value 15
40+
INFO core.basesyntax.Counter:19 After decrementing, Thread # 10, counter value 14
41+
INFO core.basesyntax.Counter:19 After decrementing, Thread # 17, counter value 11
42+
INFO core.basesyntax.Counter:19 After decrementing, Thread # 16, counter value 8
43+
INFO core.basesyntax.Counter:16 Before decrementing, Thread # 4, counter value 20
44+
INFO core.basesyntax.Counter:19 After decrementing, Thread # 11, counter value 18
45+
INFO core.basesyntax.Counter:19 After decrementing, Thread # 12, counter value 5
46+
INFO core.basesyntax.Counter:19 After decrementing, Thread # 6, counter value 6
47+
INFO core.basesyntax.Counter:19 After decrementing, Thread # 13, counter value 7
48+
INFO core.basesyntax.Counter:19 After decrementing, Thread # 18, counter value 4
49+
INFO core.basesyntax.Counter:19 After decrementing, Thread # 4, counter value 3
50+
INFO core.basesyntax.Counter:19 After decrementing, Thread # 15, counter value 2
51+
INFO core.basesyntax.Counter:19 After decrementing, Thread # 1, counter value 1
52+
```
53+
54+
As we see, all threads are accessing the same value of the variable at the same time,
55+
then they also decrease it randomly, and we can even get 1 instead of 0 in the end of execution.
56+
57+
Fix the solution to remove the race condition between the threads.
58+
Each thread should take the value that was decremented by the previous thread, and the logs should be consistent.
59+
Let's allow only one thread to execute the meaningful part of code at a time.
60+
61+
Note that you should push the file with logs to your PR, so please, do not add it to `.gitignore`.
62+
You may probably need to use the absolute path to the log file in `log4j2.xml`.

pom.xml

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<modelVersion>4.0.0</modelVersion>
66

77
<groupId>mate-academy</groupId>
8-
<artifactId>diamond</artifactId>
8+
<artifactId>decrease-counter</artifactId>
99
<version>1.0-SNAPSHOT</version>
1010

1111
<properties>
@@ -20,10 +20,9 @@
2020

2121
<dependencies>
2222
<dependency>
23-
<groupId>junit</groupId>
24-
<artifactId>junit</artifactId>
25-
<version>4.12</version>
26-
<scope>test</scope>
23+
<groupId>org.apache.logging.log4j</groupId>
24+
<artifactId>log4j-core</artifactId>
25+
<version>2.14.1</version>
2726
</dependency>
2827
</dependencies>
2928
<build>
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package core.basesyntax;
2+
3+
import org.apache.logging.log4j.LogManager;
4+
import org.apache.logging.log4j.Logger;
5+
6+
public class Counter {
7+
private static final Logger logger = LogManager.getLogger(Counter.class);
8+
private static final String MESSAGE = "%20s, Thread # %2s, counter value %2d";
9+
private int value;
10+
11+
public Counter(int value) {
12+
this.value = value;
13+
}
14+
15+
public void decreaseValue() {
16+
logger.info(String.format(MESSAGE,
17+
"Before decrementing", Thread.currentThread().getName(), value));
18+
value--;
19+
logger.info(String.format(MESSAGE,
20+
"After decrementing", Thread.currentThread().getName(), value));
21+
}
22+
}

src/main/java/core/basesyntax/HelloWorld.java

Lines changed: 0 additions & 8 deletions
This file was deleted.
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package core.basesyntax;
2+
3+
public class Main {
4+
public static void main(String[] args) {
5+
Counter counter = new Counter(20);
6+
for (int i = 1; i <= 20; i++) {
7+
new MyThread(counter, String.valueOf(i)).start();
8+
}
9+
}
10+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package core.basesyntax;
2+
3+
public class MyThread extends Thread {
4+
private final Counter counter;
5+
6+
public MyThread(Counter counter, String name) {
7+
super(name);
8+
this.counter = counter;
9+
}
10+
11+
@Override
12+
public void run() {
13+
counter.decreaseValue();
14+
}
15+
}

src/main/resources/log4j2.xml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<Configuration status="info">
3+
<Appenders>
4+
<Console name="LogToConsole" target="SYSTEM_OUT">
5+
<PatternLayout pattern="%-5level %c:%L - %msg%n"/>
6+
</Console>
7+
<File name="LogToFile" filename="logs/app.log" append="false">
8+
<PatternLayout><Pattern>%p %c:%L %m%n</Pattern></PatternLayout>
9+
</File>
10+
</Appenders>
11+
<Loggers>
12+
<Root level="info">
13+
<AppenderRef ref="LogToFile"/>
14+
<AppenderRef ref="LogToConsole"/>
15+
</Root>
16+
</Loggers>
17+
</Configuration>

src/test/java/core/basesyntax/HelloWorldTest.java

Lines changed: 0 additions & 8 deletions
This file was deleted.

0 commit comments

Comments
 (0)