Commit 22baf1b7 authored by abdullh.alsoleman's avatar abdullh.alsoleman

Semaphore_Sync

parents
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/
### IntelliJ IDEA ###
.idea/modules.xml
.idea/jarRepositories.xml
.idea/compiler.xml
.idea/libraries/
*.iws
*.iml
*.ipr
### Eclipse ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
!**/src/main/**/build/
!**/src/test/**/build/
### VS Code ###
.vscode/
### Mac OS ###
.DS_Store
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding">
<file url="file://$PROJECT_DIR$/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/src/main/resources" charset="UTF-8" />
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="MavenProjectsManager">
<option name="originalFiles">
<list>
<option value="$PROJECT_DIR$/pom.xml" />
</list>
</option>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="17" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="AutoImportSettings">
<option name="autoReloadType" value="SELECTIVE" />
</component>
<component name="ChangeListManager">
<list default="true" id="f14d66a1-1dc3-4666-9147-5cc7b3e41171" name="Changes" comment="">
<change afterPath="$PROJECT_DIR$/.gitignore" afterDir="false" />
<change afterPath="$PROJECT_DIR$/.idea/encodings.xml" afterDir="false" />
<change afterPath="$PROJECT_DIR$/.idea/misc.xml" afterDir="false" />
<change afterPath="$PROJECT_DIR$/.idea/vcs.xml" afterDir="false" />
<change afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
<change afterPath="$PROJECT_DIR$/Input/input.txt" afterDir="false" />
<change afterPath="$PROJECT_DIR$/pom.xml" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/main/java/org/example/Consumer.java" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/main/java/org/example/Producer.java" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/main/java/org/example/Writer.java" afterDir="false" />
</list>
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
<option name="LAST_RESOLUTION" value="IGNORE" />
</component>
<component name="Git.Settings">
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
</component>
<component name="MarkdownSettingsMigration">
<option name="stateVersion" value="1" />
</component>
<component name="ProjectId" id="2YjyaLFXx8wHOKZZXlc0MNVcTqc" />
<component name="ProjectLevelVcsManager" settingsEditedManually="true" />
<component name="ProjectViewState">
<option name="hideEmptyMiddlePackages" value="true" />
<option name="showLibraryContents" value="true" />
</component>
<component name="PropertiesComponent"><![CDATA[{
"keyToString": {
"RunOnceActivity.OpenProjectViewOnStart": "true",
"RunOnceActivity.ShowReadmeOnStart": "true",
"SHARE_PROJECT_CONFIGURATION_FILES": "true",
"last_opened_file_path": "C:/Users/Abdullah/Desktop/Producer_Consumer"
}
}]]></component>
<component name="RecentsManager">
<key name="CopyFile.RECENT_KEYS">
<recent name="C:\Users\Abdullah\Desktop\Producer_Consumer2" />
<recent name="C:\Users\Abdullah\Desktop\Producer_Consumer2\src\main\java\org\example" />
</key>
</component>
<component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="application-level" UseSingleDictionary="true" transferred="true" />
<component name="TaskManager">
<task active="true" id="Default" summary="Default task">
<changelist id="f14d66a1-1dc3-4666-9147-5cc7b3e41171" name="Changes" comment="" />
<created>1701053373612</created>
<option name="number" value="Default" />
<option name="presentableId" value="Default" />
<updated>1701053373612</updated>
</task>
<servers />
</component>
<component name="Vcs.Log.Tabs.Properties">
<option name="TAB_STATES">
<map>
<entry key="MAIN">
<value>
<State />
</value>
</entry>
</map>
</option>
</component>
</project>
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>Producer_Consumer2</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
</project>
\ No newline at end of file
package org.example;
import java.util.LinkedList;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.Semaphore;
public class Consumer implements Runnable {
// Object for synchronization when incrementing numLines
private Object synchronizationObject = new Object();
// Queue of lines before processing them
private Queue<String> linesQueue;
// Queue of lines after processing them
private ConcurrentLinkedQueue<String> processedLines;
// Semaphore for controlling access to the linesQueue
private Semaphore linesQueueSemaphore;
// Volatile variable to track the number of processed lines
private volatile static long numLines = 0;
// Getter for numLines
public static long getNumLines() {
return numLines;
}
// Constructor
public Consumer(LinkedList<String> linesQueue, ConcurrentLinkedQueue<String> processedLines, Semaphore linesQueueSemaphore) {
this.linesQueue = linesQueue;
this.processedLines = processedLines;
this.linesQueueSemaphore = linesQueueSemaphore;
}
// Run method to be executed when the thread starts
@Override
public void run() {
try {
// Infinite loop for continuous processing
while (true) {
try {
// Acquire the semaphore to process the lines
linesQueueSemaphore.acquire();
} catch (InterruptedException i) {
// just for Handle InterruptedException
}
// Print the name of the current thread for debugging purposes
System.out.println(Thread.currentThread().getName());
// Increment the numLines variable in a synchronized block for thread safety
synchronized (synchronizationObject) {
numLines++;
}
// Retrieve a line from the linesQueue
String line = linesQueue.poll();
if (line == null) {
break; // Exit the loop if no more lines
}
// Convert each lowercase letter to uppercase and vice versa
StringBuilder swappedString = new StringBuilder();
for (char c : line.toCharArray()) {
if (Character.isUpperCase(c)) {
swappedString.append(Character.toLowerCase(c));
} else if (Character.isLowerCase(c)) {
swappedString.append(Character.toUpperCase(c));
} else {
swappedString.append(c);
}
}
// Offer the processed line to the processedLines queue
processedLines.offer(swappedString.toString());
}
} catch (Exception e) {
// Print the exception stack trace for debugging purposes
e.printStackTrace();
}
}
}
package org.example;
import java.io.*;
import java.util.LinkedList;
import java.util.Queue;
import java.util.concurrent.Semaphore;
public class Producer implements Runnable {
// Static variable to keep track of the total number of lines produced
private static long numLines = 0;
// File to read lines from
private String file;
// Queue to store lines read from the file
private Queue<String> linesQueue;
// Semaphore to control access to the linesQueue
private Semaphore linesQueueSemaphore;
// Getter for numLines
public static long getNumLines() {
return numLines;
}
// Constructor
public Producer(String file, LinkedList<String> linesQueue) {
this.file = file;
this.linesQueue = linesQueue;
this.linesQueueSemaphore = new Semaphore(0);
}
// Getter for the linesQueueSemaphore
public Semaphore getSemaphore() {
return linesQueueSemaphore;
}
// Run method to be executed when the thread starts
@Override
public void run() {
try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
String line;
// Read lines from the file until the end is reached
while ((line = reader.readLine()) != null) {
// Offer the line to the linesQueue
linesQueue.offer(line);
// Increment the numLines variable
numLines++;
// Release the semaphore to signal that a new line is available for consumption
linesQueueSemaphore.release();
}
} catch (IOException e) {
// Print the exception stack trace for debugging purposes
e.printStackTrace();
}
}
}
package org.example;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.LinkedList;
import java.util.concurrent.*;
public class Writer {
public static void main(String[] args) {
// File paths
String inputFile = "Input/input.txt";
String outputFile = "Output/output.txt";
// Determine the number of consumer threads
int numConsumers = Runtime.getRuntime().availableProcessors();
// Create a queue to hold the lines read from the file
LinkedList<String> linesQueue = new LinkedList<>();
// Create a concurrent queue to store the processed results for each consumer
ConcurrentLinkedQueue<String> processedResults = new ConcurrentLinkedQueue<>();
// Create a producer thread to read lines from the file and put them into the linesQueue
Producer producer = new Producer(inputFile, linesQueue);
Thread producerThread = new Thread(producer);
producerThread.start();
// Create a thread pool with the specified number of consumers
ExecutorService executor = Executors.newFixedThreadPool(numConsumers);
// Submit consumer tasks to the thread pool
for (int i = 0; i < numConsumers; i++) {
Consumer consumer = new Consumer(linesQueue, processedResults, producer.getSemaphore());
executor.submit(consumer);
}
// Wait for the producer to finish
try {
producerThread.join();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
// Wait until all consumers finish processing the lines then shutdown the executor
while (true) {
if ( Producer.getNumLines() == Consumer.getNumLines()) {
executor.shutdownNow();
break;
}
}
// Write the processed results to the output file
try (BufferedWriter writer = new BufferedWriter(new FileWriter(outputFile))) {
for (String result : processedResults) {
writer.write(result);
writer.newLine();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment