Codes
Codes
printChar
// The task for printing a specified character in specified times
public class PrintChar implements Runnable {
@Override
/**
* Override the run() method to tell the system what the task to perform
*/
public void run() {
System.out.print(Thread.currentThread().getName()+" started. ");
for (int i = 0; i < times; i++) {
System.out.print(" "+charToPrint);
if(i==70){
try {
if(prev != null) {
prev.join();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
printNum
// The task class for printing number from 1 to n for a given n
public class PrintNum implements Runnable {
/**
* Construct a task for printing 1, 2, ... i
*/
public PrintNum(int n) {
lastNum = n;
}
@Override
/**
* Tell the thread how to run
*/
public void run() {
System.out.print(Thread.currentThread().getName()+" started. ");
for (int i = 1; i <= lastNum; i++) {
System.out.print(" " + i);
}
}
}
Threadsexample6
/* The last discussed version of this example. Here we are again illustrating
the usage of the join method. In this case we are informing task printB to join
thread1 by calling a method that we added (waitFor).
*/
public class ThreadsExample6 {
// Create threads
Thread thread1 = new Thread(printA);
Thread thread2 = new Thread(printB);
Thread thread3 = new Thread(print100);
printB.waitFor(thread1);
// Start threads
thread1.start();
thread2.start();
thread3.start();
thread1.join();
thread2.join();
thread3.join();
System.out.print("MAIN-DONE");
}
}
producerConsumer
/*
* In this example two threads (ProducerTask and ConsumerTask) cooperate adding
* and removing data from a shared buffer. When the buffer is full the ProducerTask
* has to wait and when the buffer is empty the ConsumerTask has to wait.
*/
import java.util.concurrent.*;
import java.util.concurrent.locks.*;
queue.offer(value);
notEmpty.signal(); // Signal notEmpty condition
}
catch (InterruptedException ex) {
ex.printStackTrace();
}
finally {
lock.unlock(); // Release the lock
}
}
value = queue.remove();
notFull.signal(); // Signal notFull condition
}
catch (InterruptedException ex) {
ex.printStackTrace();
}
finally {
lock.unlock(); // Release the lock
return value;
}
}
}
}
AccountswithSync
producerConsumer
/*
* In this example two threads (ProducerTask and ConsumerTask) cooperate adding
* and removing data from a shared buffer. When the buffer is full the ProducerTask
* has to wait and when the buffer is empty the ConsumerTask has to wait.
*/
import java.util.concurrent.*;
import java.util.concurrent.locks.*;
queue.offer(value);
notEmpty.signal(); // Signal notEmpty condition
}
catch (InterruptedException ex) {
ex.printStackTrace();
}
finally {
lock.unlock(); // Release the lock
}
}
value = queue.remove();
notFull.signal(); // Signal notFull condition
}
catch (InterruptedException ex) {
ex.printStackTrace();
}
finally {
lock.unlock(); // Release the lock
return value;
}
}
}
}
AccountWithoutSynchronization
/**
* In this example is illustrated the unpleasant situation of "race condition"
* A large number of threads are created and they modify a simple instance of
* Account. As we are not taking care about synchronization, the final result
* may vary from one execution to another.
* The difference compared to the previous example is that ExecutorService is
* not used, but threads .
*/
public class AccountWithoutSynchronization {
Countdown
/*
* In this fourth version of the program, two threads manipulate different countdown objects
* so no race conditions occur (as there is no common structure accessed by both threads).
* Each thread will continue counting on its own (however the precise order the in output is
* not predictable. You may try executing this several times and witness how the output may
vary.
* */
public class Main {
public static void main(String[] args) {
Countdown countdown = new Countdown(30);
Countdown countdown2 = new Countdown(30);
t1.start();
t2.start();
}
}
class Countdown {
private int i;
switch (Thread.currentThread().getName()) {
case "Thread 1":
color = ThreadColors.ANSI_BLUE;
break;
case "Thread 2":
color = ThreadColors.ANSI_PURPLE;
break;
default:
color = ThreadColors.ANSI_GREEN;
}
while (i > 0) {
synchronized (this) {
System.out.println(color + Thread.currentThread().getName() + ": i =" + i);
i--;
}
try {
Thread.sleep((long)(50*Math.random()));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
ThreadCooperation
/*
* In this example, two threads (DepositTask and WithdrawTask) modify
* together the balance of an account not only in a synchronized way,
* but also in cooperation. So the WithdrawTask will not withdraw if
* amount is larger than the current balance and DepositTask will wait
* if the amount would make the balance greater than 100.
*/
package Version1;
import java.util.concurrent.*;
import java.util.concurrent.locks.*;
import java.util.logging.Level;
import java.util.logging.Logger;
balance -= amount;
if(balance + depositRequest <= 100){
newWithdraw.signalAll();
}
ProducerConsumer
/*
* In this example two threads (ProducerTask and ConsumerTask) cooperate adding
* and removing data from a shared buffer. When the buffer is full the ProducerTask
* has to wait and when the buffer is empty the ConsumerTask has to wait.
*/
import java.util.concurrent.*;
import java.util.concurrent.locks.*;
value = queue.remove();
notFull.signal(); // Signal notFull condition
}
catch (InterruptedException ex) {
ex.printStackTrace();
}
finally {
lock.unlock(); // Release the lock
return value;
}
}
}
}
producerConsumerUsingBLOCKEDQUEUE
/*
* In this example two threads (ProducerTask and ConsumerTask) cooperate adding
* and removing data from a shared buffer which is implemented using blocking queues.
* If the buffer is full and the "put" method is called, then the current thread
* (ProducerTask) will have to wait.
* Alternatively, if the buffer is empty and the "take "method is called, then
* the current thread(ConsumerTask) will have to wait.
*/
import java.util.concurrent.*;
BarrierExample
/*
* Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this
license
* Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template
*/
package lab4examples;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
// Stage 3: Finalize
System.out.println("Thread " + Thread.currentThread().getName() + " is finalizing.");
Thread.sleep((long) (Math.random() * 2000));
System.out.println("Thread " + Thread.currentThread().getName() + " has finished
finalizing.");
barrier.await(); // Wait for all threads to finish finalizing
} catch (InterruptedException | BrokenBarrierException e) {
e.printStackTrace();
}
System.out.println("All done.");
}
}
}
SemaphoreTest
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package javathreads;
import java.util.concurrent.Semaphore;
// max 4 people
static Semaphore semaphore = new Semaphore(4);
MyATMThread(String name) {
this.name = name;
}
try {
System.out.println(name + " : acquiring lock...");
System.out.println(name + " : available Semaphore permits now: "
+ semaphore.availablePermits());
semaphore.acquire();
System.out.println(name + " : got the permit!");
try {
// sleep 1 second
Thread.sleep(1000);
} finally {
} catch (InterruptedException e) {
e.printStackTrace();
}
}
CyclicBarrierExample
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Random;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
*
* In this example the usage of cyclic barriers is demonstrated.
*/
public class CyclicBarrierExample {
@Override
public void run() {
String thisThreadName = Thread.currentThread().getName();
List<Integer> partialResult = new ArrayList<>();
partialResults.add(partialResult);
try {
System.out.println(thisThreadName + " waiting for others to reach barrier (rendez-
vois).");
cyclicBarrier.await();
} catch (InterruptedException e) {
// ...
} catch (BrokenBarrierException e) {
// ...
}
System.out.println(thisThreadName + " finished waiting the barrier.");
}
}
@Override
public void run() {
System.out.println(
thisThreadName + ": Computing sum of " + NUM_WORKERS
+ " workers, having " + NUM_PARTIAL_RESULTS + " results each.");
int sum = 0;
—-------------------------POSIX THREADS—---------------------------------------
Pth_hello.c
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
/*--------------------------------------------------------------------*/
int main(int argc, char* argv[]) {
long thread; /* Use long in case of a 64-bit system */
pthread_t* thread_handles;
free(thread_handles);
return 0;
} /* main */
/*-------------------------------------------------------------------*/
void *Hello(void* rank) {
long my_rank = (long) rank; /* Use long in case of 64-bit system */
return NULL;
} /* Hello */
/*-------------------------------------------------------------------*/
void Usage(char* prog_name) {
fprintf(stderr, "usage: %s <number of threads>\n", prog_name);
fprintf(stderr, "0 < number of threads <= %d\n", MAX_THREADS);
exit(0);
} /* Usage */
pth_helloV2.c
//Threads in C
/* Includes */
#include <unistd.h> /* Symbolic Constants */
#include <sys/types.h> /* Primitive System Data Types */
#include <errno.h> /* Errors */
#include <stdio.h> /* Input/Output */
#include <stdlib.h> /* General Utilities */
#include <pthread.h> /* POSIX Threads */
#include <string.h> /* String handling */
#define THREAD_NO 10
int main()
{
pthread_t threads[THREAD_NO]; /* thread variables */
thdata data[THREAD_NO]; /* structs to be passed to threads */
}
/* create threads 1 and 2 */
for(int i =0; i<THREAD_NO; i++){
pthread_create (&threads[i], NULL, (void *) &print_message_function, (void *) &data[i]);
}
/* Main block now waits for both threads to terminate, before it exits
If main block exits, both threads exit, even if the threads have not
finished their work */
for(int i =0; i<THREAD_NO; i++){
pthread_join(threads[i], NULL);
}
/* exit */
exit(0);
} /* main() */
/**
* print_message_function is used as the start routine for the threads used
* it accepts a void pointer
**/
void print_message_function ( void *ptr )
{
thdata *data;
data = (thdata *) ptr; /* type cast to a pointer to thdata */
/* do the work */
printf("Thread %d says %s \n", data->thread_no, data->message);
pthread_exit(0); /* exit */
} /* print_message_function ( void *ptr ) */
Threads_printing.c
//Threads in C
/* Includes */
#include <unistd.h> /* Symbolic Constants */
#include <sys/types.h> /* Primitive System Data Types */
#include <errno.h> /* Errors */
#include <stdio.h> /* Input/Output */
#include <stdlib.h> /* General Utilities */
#include <pthread.h> /* POSIX Threads */
#include <string.h> /* String handling */
} thdata;
int main()
{
pthread_t thread1, thread2, thread3; /* thread variables */
thdata data1, data2; /* structs to be passed to threads */
/* Main block now waits for both threads to terminate, before it exits
If main block exits, both threads exit, even if the threads have not
finished their work */
pthread_join(thread1, NULL);
pthread_join(thread2, NULL);
pthread_join(thread3, NULL);
/* exit */
exit(0);
} /* main() */
/**
* print_message_function is used as the start routine for the threads used
* it accepts a void pointer
**/
void print_chars_function ( void *ptr )
{
thdata *data;
data = (thdata *) ptr; /* type cast to a pointer to thdata */
/* do the work */
for(int i = 0; i<data->number; i++){
printf("%c\n", data->c);
if(i%5==0) sleep(1);
}
pthread_exit(0); /* exit */
} /* print_message_function ( void *ptr ) */
/* do the work */
for(int i = 1; i<=n; i++){
printf("%d\n", i);
if(i % 20 == 0)
sleep(1);
pthread_exit(0); /* exit */
} /* print_message_function ( void *ptr ) */
AccountWithoutSync.c
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
int balance = 0;
void deposit() {
int newbalance;
newbalance = balance + 1;
printf("The balance now is %d.\n",newbalance);
balance = newbalance;
//pthread_exit(0);
}
int main()
{
int i =0;
pthread_t threads[100];
exit(0);
}
AccountWithSync.c
#include <unistd.h> /* Symbolic Constants */
#include <sys/types.h> /* Primitive System Data Types */
#include <errno.h> /* Errors */
#include <stdio.h> /* Input/Output */
#include <stdlib.h> /* General Utilities */
#include <pthread.h> /* POSIX Threads */
#include <string.h> /* String handling */
int balance = 0;
pthread_mutex_t mutex;
void deposit() {
int newbalance;
pthread_mutex_lock(&mutex);
newbalance = balance + 1;
balance = newbalance;
printf("The balance now is %d.\n",newbalance);
pthread_mutex_unlock(&mutex);
}
int main()
{
int i =0;
pthread_t threads[100];
exit(0);
}
threadCooperation3.c
/*
* This example is a modification of the threadcooperation.c example.
* The DepositTask thread is allowed to make a deposit only if the new
* balance would not exceed the MAX_INSURANCE_LIMIT, otherwise it will
* wait for some withdrawals to be made.
* COMPARE THIS WITH THE SOLUTION IN JAVA
*/
void deposit();
void withdraw();
int balance=0;
pthread_mutex_t mutex;
pthread_cond_t cond_var, cond_var2;
int main()
{
pthread_t threads[2]; /* thread variables */
int i;
srand(time(NULL));
exit(0);
} /* main() */
void deposit(){
while(1){
pthread_mutex_lock(&mutex);
int amount = rand()%40 +1;
while(balance+amount > MAX_INSURANCE_LIMIT){
printf("Cannot deposit %d, waiting ...\n",amount);
pthread_cond_wait(&cond_var2, &mutex);
}
int newBalance=balance+amount;
printf("Add %d. Balance now is %d\n",amount, newBalance);
balance=newBalance;
pthread_cond_broadcast(&cond_var);
pthread_mutex_unlock(&mutex);
sleep(1);
}
}
void withdraw(){
while(1) {
pthread_mutex_lock(&mutex);
int withdrawAmount = rand()%20 +1;
while(balance<withdrawAmount){
printf("\t\t\tCannot withdraw %d, waiting ...\n",withdrawAmount);
pthread_cond_wait(&cond_var, &mutex);
}
int newBalance = balance-withdrawAmount;
printf("\t\t\tWithdrew %d. Balance now is %d\n", withdrawAmount, newBalance);
balance = newBalance;
pthread_cond_broadcast(&cond_var2);
pthread_mutex_unlock(&mutex);
sleep(1);
}
}
piEstimation.c
/*
* This example is a modification of the threadcooperation.c example.
* The DepositTask thread is allowed to make a deposit only if the new
* balance would not exceed the MAX_INSURANCE_LIMIT, otherwise it will
* wait for some withdrawals to be made.
* COMPARE THIS WITH THE SOLUTION IN JAVA
*/
void deposit();
void withdraw();
int balance=0;
pthread_mutex_t mutex;
pthread_cond_t cond_var, cond_var2;
int main()
{
pthread_t threads[2]; /* thread variables */
int i;
srand(time(NULL));
exit(0);
} /* main() */
void deposit(){
while(1){
pthread_mutex_lock(&mutex);
int amount = rand()%40 +1;
while(balance+amount > MAX_INSURANCE_LIMIT){
printf("Cannot deposit %d, waiting ...\n",amount);
pthread_cond_wait(&cond_var2, &mutex);
}
int newBalance=balance+amount;
printf("Add %d. Balance now is %d\n",amount, newBalance);
balance=newBalance;
pthread_cond_broadcast(&cond_var);
pthread_mutex_unlock(&mutex);
sleep(1);
}
}
void withdraw(){
while(1) {
pthread_mutex_lock(&mutex);
int withdrawAmount = rand()%20 +1;
while(balance<withdrawAmount){
printf("\t\t\tCannot withdraw %d, waiting ...\n",withdrawAmount);
pthread_cond_wait(&cond_var, &mutex);
}
int newBalance = balance-withdrawAmount;
printf("\t\t\tWithdrew %d. Balance now is %d\n", withdrawAmount, newBalance);
balance = newBalance;
pthread_cond_broadcast(&cond_var2);
pthread_mutex_unlock(&mutex);
sleep(1);
}
}
Timer.h
/* File: timer.h
*
* Purpose: Define a macro that returns the number of seconds that
* have elapsed since some point in the past. The timer
* should return times with microsecond accuracy.
*
* Note: The argument passed to the GET_TIME macro should be
* a double, *not* a pointer to a double.
*
* Example:
* #include "timer.h"
* ...
* double start, finish, elapsed;
* ...
* GET_TIME(start);
* ...
* Code to be timed
* ...
* GET_TIME(finish);
* elapsed = finish - start;
* printf("The code to be timed took %e seconds\n", elapsed);
*
* IPP: Section 3.6.1 (pp. 121 and ff.) and Section 6.1.2 (pp. 273 and ff.)
*/
#ifndef _TIMER_H_
#define _TIMER_H_
#include <sys/time.h>
#endif