Operating System
P1_NoThreads.java
P1_NoThreads.java
package
Threads_Synchronization
;
public
class
P1_NoThreads
{
public
static
void
function1
(){
for
(
int
i
=
0
;
i
<
20
;
i
++
)
{
try
{
System
.
out
.
println
(
"function 1 is running for iteration number "
+
i
);
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
}
}
public
static
void
function2
(){
for
(
int
j
=
0
;
j
<
20
;
j
++
)
{
try
{
System
.
out
.
println
(
"function 2 is running for iteration number "
+
j
);
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
}
}
public
static
void
main
(
String
[]
args
)
{
//main thread running both function1 and function2
function1
();
//call function 1
function2
();
//call function 2
}
}
__MACOSX/._P1_NoThreads.java
Question1_WithdrawDeposit.java
Question1_WithdrawDeposit.java
package
Threads_Synchronization
;
import
java
.
util
.
concurrent
.
Semaphore
;
import
java
.
util
.
concurrent
.
locks
.
Lock
;
import
java
.
util
.
concurrent
.
locks
.
ReentrantLock
;
public
class
Question1_WithdrawDeposit
{
/*
* In this question use semaphore(s) to enable process synchronization
*
* Thread 1 and thread 2 (in the main function) share a single bank account (initial balance of 1000$).
* thread 1 can deposit certain input amount to the balance only if the current balance is less than 2000$
* thread 2 can withdraw certain input amount from the balance only if the current balance is greater than or equal to the input amount.
*
*/
// shared resources between thread 1 and thread 2 are:
public
static
int
balance
=
1000
;
//the initial value of the account's balance
//DONOT CHANGE THIS VARIABLE
// add below any further resources you think the deposit and withdraw threads/functions must share
//--------------------------------------------end of shared resources section
// this function simply displays the current balance of the shared account and which thread made the call
// DONOT CHANGE THIS FUNCTION
public
static
void
displayStatus
()
{
if
(
Thread
.
currentThread
().
getName
().
equals
(
"withdraw"
))
System
.
out
.
println
(
"The withdraw function successfully took the amount and the current value of the account's balance is :"
+
balance
+
"$"
);
else
System
.
out
.
println
(
"The deposit function successfully added the amount and the current value of the account's balance is :"
+
balance
+
"$"
);
}
// this function accepts an input integer amount value to deposit into the shared account
public
static
void
Deposit
(
int
amount
){
try
{
System
.
out
.
println
(
"The deposit function is trying to add "
+
amount
+
"$ to the shared balance"
+
balance
+
"$"
);
// Deposit the input amount to the balance only if the current balance is less than 2000$
// Deposit doesn't wait until this condition is true (If the condition is false, skip adding the amount), thus use if statements rather than waiting while loops
// Call the displayStatus() function after you deposit the amount and before release the lock
// Implement the deposit functionality, as detailed above, in the area below
//--------------------------------------------end of Deposit function
}
catch
(
Exception
e
)
{
System
.
out
.
println
(
"Problem with the deposite function "
+
e
.
toString
());
}
}
// this function accepts an input integer amount value to withdraw from the shared account
public
static
void
Withdraw
(
int
amount
){
try
{
System
.
out
.
println
(
"The withdraw is trying to remove "
+
amount
+
"$ from the shared balance"
+
balance
+
"$"
);
// withdraw the input amount from the balance only if the current balance is greater than or equal to input amount
// Withdraw doesn't wait until this condition is true (if the condition is false, skip withdrawing the amount), thus use if statements rather than waiting while loops
// Call the displayStatus() function after you remove the amount and before release the lock
// Implement the withdraw functionality, as detailed above, in the area below
//--------------------------------------------end of Withdraw function
}
catch
(
Exception
e
)
{
System
.
out
.
println
(
"Problem with the withdraw function "
+
e
.
toString
());
}
}
// this is the main function
// DONOT CHANGE THIS SECTION
public
static
void
main
(
String
[]
args
)
{
//create thread 1 to run function 1
Thread
thread1
=
new
Thread
(
new
Runnable
()
{
@
Override
public
void
run
()
{
while
(
true
)
{
try
{
Deposit
(
200
+
(
int
)(
Math
.
random
()
*
1000
));
//random value between 200 and 1000$
Thread
.
sleep
(
200
+
(
int
)(
Math
.
random
()
*
500
));
//random delay between 200 and 500
}
catch
(
Exception
e
)
{
System
.
out
.
println
(
"Problem with thread 1 "
+
e
.
toString
());
}
}
}
});
//create thread 2 to run function 2
Thread
thread2
=
new
Thread
(
new
Runnable
()
{
@
Override
public
void
run
()
{
while
(
true
)
{
try
{
Withdraw
(
200
+
(
int
)(
Math
.
random
()
*
1000
));
//random value between 200 and 1000$
Thread
.
sleep
(
200
+
(
int
)(
Math
.
random
()
*
500
));
//random delay between 200 and 500
}
catch
(
Exception
e
)
{
System
.
out
.
println
(
"Problem with thread 2 "
+
e
.
toString
());
}
}
}
});
//ask the threads to start running
thread1
.
setName
(
"deposit"
);
thread1
.
start
();
thread2
.
setName
(
"withdraw"
);
thread2
.
start
();
}
}
__MACOSX/._Question1_WithdrawDeposit.java
P4_Semaphore.java
P4_Semaphore.java
package
Threads_Synchronization
;
import
java
.
util
.
concurrent
.
*
;
public
class
P4_Semaphore
{
/*
Important to note:
Mutex Lock in literature uses acquire() and release()
in Java these functions are lock() and unlock() respectively
Semaphore in literature uses wait() and signal()
in Java these functions are acquire() and release() respectively
*/
//semaphore lock
//counting semaphore with two instances, change the number of instances and track the acquire/release sequence
public
static
Semaphore
semaphore
=
new
Semaphore
(
2
);
public
static
void
function1
(){
for
(
int
i
=
0
;
i
<
5
;
i
++
)
{
try
{
System
.
out
.
println
(
"function 1 trying to acquire the lock"
);
semaphore
.
acquire
();
System
.
out
.
println
(
"function 1 acquired the lock ... start the critical section"
);
//critical section
System
.
out
.
println
(
"function 1 Locks remaining >> "
+
semaphore
.
availablePermits
());
//end of critical section
semaphore
.
release
();
System
.
out
.
println
(
"exit the critical section ... function 1 Locks Released"
);
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
}
}
public
static
void
function2
(){
for
(
int
j
=
0
;
j
<
5
;
j
++
)
{
try
{
System
.
out
.
println
(
"function 2 trying to acquire the lock"
);
semaphore
.
acquire
();
System
.
out
.
println
(
"function 2 acquired the lock ... start the critical section"
);
//critical section
System
.
out
.
println
(
"function 2 Locks remaining >> "
+
semaphore
.
availablePermits
());
//end of critical section
semaphore
.
release
();
System
.
out
.
println
(
"exit the critical section ... function 2 Locks Released"
);
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
}
}
public
static
void
main
(
String
[]
args
)
{
//create thread 1 to run function 1
Thread
thread1
=
new
Thread
(
new
Runnable
()
{
@
Override
public
void
run
()
{
function1
();
}
});
//create thread 2 to run function 2
Thread
thread2
=
new
Thread
(
new
Runnable
()
{
@
Override
public
void
run
()
{
function2
();
}
});
thread1
.
start
();
thread2
.
start
();
}
}
__MACOSX/._P4_Semaphore.java
P2_SimpleThreads.java
P2_SimpleThreads.java
package
Threads_Synchronization
;
public
class
P2_SimpleThreads
{
public
static
void
function1
(){
for
(
int
i
=
0
;
i
<
20
;
i
++
)
{
try
{
System
.
out
.
println
(
"function 1 is running for iteration number "
+
i
);
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
}
}
public
static
void
function2
(){
for
(
int
j
=
0
;
j
<
20
;
j
++
)
{
try
{
System
.
out
.
println
(
"function 2 is running for iteration number "
+
j
);
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
}
}
public
static
void
main
(
String
[]
args
)
{
//create thread 1 to run function 1
Thread
thread1
=
new
Thread
(
new
Runnable
()
{
@
Override
public
void
run
()
{
function1
();
}
});
//create thread 2 to run function 2
Thread
thread2
=
new
Thread
(
new
Runnable
()
{
@
Override
public
void
run
()
{
function2
();
}
});
//ask the threads to start running
thread1
.
start
();
thread2
.
start
();
}
}
__MACOSX/._P2_SimpleThreads.java
Question3_SortingArrays.java
Question3_SortingArrays.java
package
Threads_Synchronization
;
import
java
.
util
.
Random
;
import
java
.
util
.
concurrent
.
locks
.
Lock
;
import
java
.
util
.
concurrent
.
locks
.
ReentrantLock
;
public
class
Question3_SortingArrays
{
/*
* In this question use mutex lock(s) or semaphore(s) to enable process synchronization
*
* Thread 1 and thread 2 share a single buffer (1D Array), where:
* thread 1 sorts the items of the buffer in ascending order
* thread 2 sorts the items of the buffer in descending order
*
*/
// shared resources between thread 1 and thread 2 are:
// DONOT CHANGE THESE VARIABLE
public
static
int
BufferSize
=
10
;
//the size of the buffer
public
static
int
buffer
[]
=
new
int
[
BufferSize
];
//the shared buffer
// add any further resources you think Ascending() and Descending()functions must share below
//--------------------------------------------end of shared resources section
// this function simply displays the content of the shared buffer and which thread made the call
// DONOT CHANGE THIS FUNCTION
public
static
void
displayStatus
()
{
if
(
Thread
.
currentThread
().
getName
().
equals
(
"ascending"
))
System
.
out
.
println
(
"Ascending successfully sorted the array"
);
else
System
.
out
.
println
(
"Descending successfully sorted the array"
);
System
.
out
.
print
(
" the "
+
Thread
.
currentThread
().
getName
()
+
" is displaying the content of the buffer: "
);
for
(
int
i
=
0
;
i
<
BufferSize
;
i
++
)
{
System
.
out
.
print
(
buffer
[
i
]
+
" "
);
}
System
.
out
.
println
();
}
// this function sorts the shared buffer in ascending order
public
static
void
Ascending
(){
try
{
System
.
out
.
println
(
"The Ascending is trying to sort the shared buffer"
);
// Sort the buffer in ascending order
// Call displayStatus after you sort and before release the lock
// Implement the Ascending functionality in the area below
//--------------------------------------------end of Ascending function
}
catch
(
Exception
e
)
{
System
.
out
.
println
(
"Problem with the Ascending function "
+
e
.
toString
());
}
}
// this function sorts the shared buffer in descending order
public
static
void
Descending
(){
try
{
System
.
out
.
println
(
"The Descending is trying to sort the shared buffer"
);
// Sort the buffer in descending order
// Call displayStatus after you sort and before release the lock
// Implement the Descending functionality in the area below
//--------------------------------------------end of Descending function
}
catch
(
Exception
e
)
{
System
.
out
.
println
(
"Problem with the Descending function "
+
e
.
toString
());
}
}
// this is the main function
// DONOT CHANGE THIS SECTION
public
static
void
main
(
String
[]
args
)
{
for
(
int
i
=
0
;
i
<
BufferSize
;
i
++
)
{
buffer
[
i
]
=
1
+
new
Random
().
nextInt
(
9
);
//random value between 1 and 10
}
//create thread 1 to run function 1
Thread
thread1
=
new
Thread
(
new
Runnable
()
{
@
Override
public
void
run
()
{
while
(
true
)
{
try
{
Ascending
();
//sort in ascending order the shared buffer
Thread
.
sleep
(
200
+
(
int
)(
Math
.
random
()
*
500
));
//random delay between 200 and 500
}
catch
(
Exception
e
)
{
System
.
out
.
println
(
"Problem with thread 1 "
+
e
.
toString
());
}
}
}
});
//create thread 2 to run function 2
Thread
thread2
=
new
Thread
(
new
Runnable
()
{
@
Override
public
void
run
()
{
while
(
true
)
{
try
{
Descending
();
//sort in ascending order the shared buffer
Thread
.
sleep
(
200
+
(
int
)(
Math
.
random
()
*
500
));
//random delay between 200 and 500
}
catch
(
Exception
e
)
{
System
.
out
.
println
(
"Problem with thread 2 "
+
e
.
toString
());
}
}
}
});
//ask the threads to start running
thread1
.
setName
(
"ascending"
);
thread1
.
start
();
thread2
.
setName
(
"descending"
);
thread2
.
start
();
}
}
__MACOSX/._Question3_SortingArrays.java
Question2_ProducerConsumer.java
Question2_ProducerConsumer.java
package
Threads_Synchronization
;
import
java
.
util
.
Random
;
import
java
.
util
.
concurrent
.
locks
.
Lock
;
import
java
.
util
.
concurrent
.
locks
.
ReentrantLock
;
public
class
Question2_ProducerConsumer
{
/*
* In this question use mutex lock(s) to enable process synchronization
*
* Thread 1 and thread 2 share a single buffer (1D Array), where:
* thread 1 adds item to the shared buffer only if there is a free space
* thread 2 consumes item from the shared buffer only if there is an available item in the buffer
*
*/
// shared resources between thread 1 and thread 2 are:
// DONOT CHANGE THESE VARIABLE
public
static
int
BufferSize
=
5
;
//the size of the buffer
public
static
int
count
=
0
;
//keeps track of the number of items currently in buffer
public
static
int
buffer
[]
=
new
int
[
BufferSize
];
//the buffer to add data into and consume data from
// add below any further resources you think the producer and consumer functions must share
//--------------------------------------------end of shared resources section
// this function simply displays the content of the shared buffer and which thread made the call
// DONOT CHANGE THIS FUNCTION
public
static
void
displayStatus
()
{
if
(
Thread
.
currentThread
().
getName
().
equals
(
"producer"
))
System
.
out
.
println
(
"Producer successfully added the new item to the shared buffer"
);
else
System
.
out
.
println
(
"Consumer successfully removed an item from the shared buffer"
);
System
.
out
.
print
(
" the "
+
Thread
.
currentThread
().
getName
()
+
" is displaying the content of the buffer: "
);
for
(
int
i
=
0
;
i
<
BufferSize
;
i
++
)
{
System
.
out
.
print
(
buffer
[
i
]
+
" "
);
}
System
.
out
.
println
(
" and the value of the count is "
+
count
);
}
// this function accepts an input integer item to be added to the shared buffer
public
static
void
Producer
(
int
item
){
try
{
System
.
out
.
println
(
"The Producer is trying to add the new item ("
+
item
+
") to the shared buffer"
);
// Add the input item only if there is a free space in the shared buffer
// Producer waits until this condition is true, thus use while rather than if statements
// Call the displayStatus() function after you add the item and before release the lock
// Implement the producer functionality in the area below
//--------------------------------------------end of Producer function
}
catch
(
Exception
e
)
{
System
.
out
.
println
(
"Problem with the producer function "
+
e
.
toString
());
}
}
// this function removes an item from the shared buffer
public
static
void
Consumer
(){
try
{
System
.
out
.
println
(
"The Consumer is trying to consume the ready item from the buffer"
);
// Consume one item (overwrite its value with -1) from the buffer only if there is an available item in the buffer
// Consumer waits until this condition is true, thus use while rather than if statements
// Call the displayStatus() function after you remove the item and before release the lock
// Implement the consumer functionality in the area below
//--------------------------------------------end of Consumer function
}
catch
(
Exception
e
)
{
System
.
out
.
println
(
"Problem with the consumer function "
+
e
.
toString
());
}
}
// this is the main function
// DONOT CHANGE THIS SECTION
public
static
void
main
(
String
[]
args
)
{
count
=
0
;
for
(
int
i
=
0
;
i
<
BufferSize
;
i
++
)
{
buffer
[
i
]
=
-
1
;
//free spots
}
//create thread 1 to run function 1
Thread
thread1
=
new
Thread
(
new
Runnable
()
{
@
Override
public
void
run
()
{
while
(
true
)
{
try
{
Producer
(
1
+
new
Random
().
nextInt
(
9
));
//random value between 1 and 10
Thread
.
sleep
(
200
+
(
int
)(
Math
.
random
()
*
500
));
//random delay between 200 and 500
}
catch
(
Exception
e
)
{
System
.
out
.
println
(
"Problem with thread 1 "
+
e
.
toString
());
}
}
}
});
//create thread 2 to run function 2
Thread
thread2
=
new
Thread
(
new
Runnable
()
{
@
Override
public
void
run
()
{
while
(
true
)
{
try
{
Consumer
();
Thread
.
sleep
(
200
+
(
int
)(
Math
.
random
()
*
500
));
//random delay between 200 and 500
}
catch
(
Exception
e
)
{
System
.
out
.
println
(
"Problem with thread 2 "
+
e
.
toString
());
}
}
}
});
//ask the threads to start running
thread1
.
setName
(
"producer"
);
thread1
.
start
();
thread2
.
setName
(
"consumer"
);
thread2
.
start
();
}
}
__MACOSX/._Question2_ProducerConsumer.java
P3_MutexLocks.java
P3_MutexLocks.java
package
Threads_Synchronization
;
import
java
.
util
.
concurrent
.
locks
.
Lock
;
import
java
.
util
.
concurrent
.
locks
.
ReentrantLock
;
public
class
P3_MutexLocks
{
/*
Important to note:
Mutex Lock in literature uses acquire() and release()
in Java these functions are lock() and unlock() respectively
Semaphore in literature uses wait() and signal()
in Java these functions are acquire() and release() respectively
*/
public
static
Lock
lock
=
new
ReentrantLock
();
//mutex lock
public
static
int
count
=
0
;
//shared variable
public
static
void
function1
(){
for
(
int
i
=
0
;
i
<
5
;
i
++
)
{
try
{
System
.
out
.
println
(
"function 1 trying to acquire the lock"
);
lock
.
lock
();
System
.
out
.
println
(
"function 1 acquired the lock ... start the critical section"
);
//critical section
count
++
;
System
.
out
.
println
(
"function 1 updated the count to "
+
count
);
//end of critical section
lock
.
unlock
();
System
.
out
.
println
(
"exit the critical section ... function 1 released the lock"
);
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
}
}
public
static
void
function2
(){
for
(
int
j
=
0
;
j
<
5
;
j
++
)
{
try
{
System
.
out
.
println
(
"function 2 trying to acquire the lock"
);
lock
.
lock
();
System
.
out
.
println
(
"function 2 acquired the lock ... start the critical section"
);
//critical section
count
++
;
System
.
out
.
println
(
"function 2 updated the count to "
+
count
);
//end of critical section
lock
.
unlock
();
System
.
out
.
println
(
"exit the critical section ... function 2 released the lock"
);
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
}
}
public
static
void
main
(
String
[]
args
)
{
//create thread 1 to run function 1
Thread
thread1
=
new
Thread
(
new
Runnable
()
{
@
Override
public
void
run
()
{
function1
();
}
});
//create thread 2 to run function 2
Thread
thread2
=
new
Thread
(
new
Runnable
()
{
@
Override
public
void
run
()
{
function2
();
}
});
thread1
.
start
();
thread2
.
start
();
}
}