task 3
This commit is contained in:
50
scala_project_2025/src/ConcurrencyTroubles.scala
Normal file
50
scala_project_2025/src/ConcurrencyTroubles.scala
Normal file
@@ -0,0 +1,50 @@
|
||||
package example
|
||||
import java.util.concurrent.locks.ReentrantLock
|
||||
|
||||
object ConcurrencyTroubles {
|
||||
private var value1: Int = 1000
|
||||
private var value2: Int = 0
|
||||
private var sum: Int = 0
|
||||
private val lock = new ReentrantLock()
|
||||
|
||||
def moveOneUnit(): Unit = {
|
||||
lock.lock()
|
||||
value1 -= 1
|
||||
value2 += 1
|
||||
if(value1 == 0) {
|
||||
value1 = 1000
|
||||
value2 = 0
|
||||
}
|
||||
lock.unlock()
|
||||
}
|
||||
|
||||
def updateSum(): Unit = {
|
||||
sum = value1 + value2
|
||||
}
|
||||
|
||||
def execute(): Unit = {
|
||||
while(true) {
|
||||
moveOneUnit()
|
||||
updateSum()
|
||||
Thread.sleep(50)
|
||||
}
|
||||
}
|
||||
|
||||
// This is the "main" method, the entry point of execution.
|
||||
// It could have been placed in a different file.
|
||||
def main(args: Array[String]): Unit = {
|
||||
for (i <- 1 to 2) {
|
||||
val thread = new Thread {
|
||||
override def run = execute()
|
||||
}
|
||||
thread.start()
|
||||
}
|
||||
|
||||
while(true) {
|
||||
updateSum()
|
||||
println(sum + " [" + value1 + " " + value2 + "]")
|
||||
Thread.sleep(100)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -65,10 +65,25 @@ object Hello extends App {
|
||||
// Task 2 b
|
||||
// There is no significant difference
|
||||
|
||||
// Task 3
|
||||
}
|
||||
object ThreadsMain extends App {
|
||||
val t: Thread = Thread.currentThread
|
||||
val name = t.getName
|
||||
println(s"I am the thread $name")
|
||||
// Task 3 a
|
||||
def create_thread(body: => Unit) : Thread = {
|
||||
new Thread {
|
||||
override def run() = body
|
||||
}
|
||||
}
|
||||
|
||||
// Task 3 b
|
||||
|
||||
// The code is supposed to create a sum that equals 1000 from two numbers which are incremented and essentially taken the modulo of 1001 of. Where it prints out the sum and the to values it adds. The first number is decremented from 1000 until 0 and then set to 1000 again, the second number is incremented from 0 until 1000 and then set to 0. Since there are 2 different threads changing the values being added, each number is supposed to be decreasing or increasing by four each print since it waits for 100 ms while each thread modifying value1 and value2 only waits 50.
|
||||
//
|
||||
// The code is not working as expected since the sum does not always equal 1000, and the change in values displayed are not consistent.
|
||||
//
|
||||
// The issue is a data race, one example being that either value1 or value2 is being modified right before the updateSum() function runs such that the sum no longer equals 1000.
|
||||
//
|
||||
// Because of immutability and the fact that oz waits for variables to be bound this would not be possible to recreate, unless it stored the data in some globally mutable place, like files.
|
||||
//
|
||||
// If you were to have to persons writing to the same document as a way to collaborate, each person might replace the same word with different things and the last thing which is being written to the document ends up being the result and might not depend on who typed last.
|
||||
//
|
||||
// Task 3 c
|
||||
// this.synchronized {} can be used to sync the move one unit function. Reentrantlock can be used to make explicit locks for the variables.
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user