Register   Login   About   Study   Enterprise   Share
Internet / AI Technology University (ITU/AITU)
Fast Login - available after registration







|

Top Links: >> 80. Technology >> Internet Technology Summit Program >> 3. Threads and Network >> 3.1. Threads
Current Topic: 3.1.4. Thread Safety
You have a privilege to create a quiz (QnA) related to this subject and obtain creativity score...
Too many cooks spoil the broth. When several threads operate on the same data - the data can be corrupted, the value of data maybe unpredictable.
For example, in the SimpleGame example, x and y coordinates are shared by two threads. The periodic mover-thread changed these values and also the same values are changed by a user touching the keyboard.

If, by chance, both threads try to access these coordinates at the same time, the results are not well predictable.

This situation is called race condition, when two pieces of code compete for access to data. By the way, the winner is the last one who overwrites any change done by the first thread.

To prevent these troubles, Java introduced the synchronized keyword and a related mechanism that allows a synchronized thread to finish its work before any other thread can start.
This means that threads can access serialized or locked code/data once at a time, which makes data safe. Developers call it thread-safe code.

Thread-safety is a concern, which comes up when an application closely interact with an operating system.
Networking, drawing a heavy-weight screen on a display, database access, using common variables on a server side by multiple users, for example a counter of visitors.

In such cases we might choose thread-safe Java classes. For example, Hashtable or ConcurrentHashMap are more safe than light-weight HashMap, while they keep same functionality.

You also need to think of thread-safe behavior/methods.
For example, the method remove() in any implementation of the List interface will not be thread-safe, especially in the loop. Even synchronize version of the method will not help.

But in the most cases making threads to work sequentially, not in parallel, is a safety option.

It is obvious that synchronization slows down performance of a program. To minimize the impact, select for synchronization the smallest piece of code where critical race conditions occur.

In the SimpleGame this critical piece of code was in the keyTyped() method. Both threads called this method to change data.

We cannot change the method signature by adding the synchronized keyword, because this method is defined not by us, but by the KeyListener interface.
But we can move selected code to another method, which we make synchronized.
This is our current code that we need to make thread-safe.


/**
* As a KeyListener this class MUST implement three methods below.
* The program uses only one of them, keyTyped(), to handle key events
* Not all keys are handled, but some change the calculations of coordinates, color, and size of a target.
* On each key event, generated by a thread or initiated by a user, this method repaint the target.
* @param key event
*/
public void keyTyped(KeyEvent e) {
char command = e.getKeyChar();
if(command == '0') {
x = 0;
y = 0;
} else if(command == '>') {
weight +=5;
} else if(command == '<') {
weight -=5;
} else if(command == 'u') {
y -= 10;
color = Color.yellow;
} else if(command == 'd') {
y += 10;
color = Color.DARK_GRAY;
} else if(command == 'l') {
x -= 10;
color = Color.LIGHT_GRAY;
} else if(command == 'r') {
x += 10;
color = Color.red;
} else if(command == 'b') {
color = Color.blue;
} else {
x += 10;
y += 10;
}
if(x == 540 && y == 40 && weight == 40 && color == Color.red) {
endOfGame = true;
}
repaint();
}



We modify our code above to the following.

public void keyTyped(KeyEvent e) {
// the command variable is internal for the method,
// it is not shared and thread-safe
char command = e.getKeyChar();
// we move our code that changes shared data to a new method
handleKey(command);
// repaint does not change the data and
// for the paint process multithreading is extremely important
repaint();
}
/**
* thread-safe key handler
* @param command
*/
public synchronized void handleKey(char command) {
if(command == '0') {
x = 0;
y = 0;
} else if(command == '>') {
weight +=5;
} else if(command == '<') {
weight -=5;
} else if(command == 'u') {
y -= 10;
color = Color.yellow;
} else if(command == 'd') {
y += 10;
color = Color.DARK_GRAY;
} else if(command == 'l') {
x -= 10;
color = Color.LIGHT_GRAY;
} else if(command == 'r') {
x += 10;
color = Color.red;
} else if(command == 'b') {
color = Color.blue;
} else {
x += 10;
y += 10;
}
if(x == 540 && y == 40 && weight == 40) {
endOfGame = true;
}
}
Was it clear so far?


Assignments:

1. Modify and run again the SimpleGame class
2. You might not notice any changes as the race condition that might happen in the previous version is a very rare although possible occasion.
| Check Your Progress | Propose QnA | Have a question or comments for open discussion?
<br/>/**
<br/> * As a KeyListener this class MUST implement three methods below.
<br/> * The program uses only one of them, keyTyped(), to handle key events
<br/> * Not all keys are handled, but some change the calculations of coordinates, color, and size of a target.
<br/> * On each key event, generated by a thread or initiated by a user, this method repaint the target.
<br/> * @param key event
<br/> */
<br/>    public void keyTyped(KeyEvent e) {
<br/>        char command = e.getKeyChar();
<br/>        if(command == '0') {
<br/>        	x = 0;
<br/>        	y = 0;
<br/>        } else if(command == '>') {
<br/>        	weight +=5;
<br/>        } else if(command == '<') {
<br/>        	weight -=5;
<br/>        } else if(command == 'u') {
<br/>        	y -= 10;
<br/>        	color = Color.yellow;
<br/>        } else if(command == 'd') {
<br/>        	y += 10;
<br/>        	color = Color.DARK_GRAY;
<br/>        } else if(command == 'l') {
<br/>        	x -= 10;
<br/>        	color = Color.LIGHT_GRAY;
<br/>        } else if(command == 'r') {
<br/>        	x += 10;
<br/>        	color = Color.red;
<br/>        } else if(command == 'b') {
<br/>        	color = Color.blue;
<br/>        } else {
<br/>	        x += 10;
<br/>	        y += 10;
<br/>        }
<br/>        if(x == 540 && y == 40 && weight == 40 && color == Color.red) {
<br/>        	endOfGame = true;
<br/>        }
<br/>        repaint();	
<br/>    }
<br/><hr>
<br/>
<br/>We modify our code above to the following.
<br/>
<br/>	public void keyTyped(KeyEvent e) {
<br/>        // the command variable is internal for the method, 
<br/>        // it is not shared and thread-safe
<br/>        char command = e.getKeyChar();
<br/>        // we move our code that changes shared data to a new method
<br/>        handleKey(command);
<br/>        // repaint does not change the data and 
<br/>        // for the paint process multithreading is extremely important
<br/>        repaint();
<br/>	}
<br/>	/**
<br/>	 * thread-safe key handler
<br/>	 * @param command
<br/>	 */
<br/>	public synchronized void handleKey(char command) {
<br/>        if(command == '0') {
<br/>        	x = 0;
<br/>        	y = 0;
<br/>        } else if(command == '>') {
<br/>        	weight +=5;
<br/>        } else if(command == '<') {
<br/>        	weight -=5;
<br/>        } else if(command == 'u') {
<br/>        	y -= 10;
<br/>        	color = Color.yellow;
<br/>        } else if(command == 'd') {
<br/>        	y += 10;
<br/>        	color = Color.DARK_GRAY;
<br/>        } else if(command == 'l') {
<br/>        	x -= 10;
<br/>        	color = Color.LIGHT_GRAY;
<br/>        } else if(command == 'r') {
<br/>        	x += 10;
<br/>        	color = Color.red;
<br/>        } else if(command == 'b') {
<br/>        	color = Color.blue;
<br/>        } else {
<br/>	        x += 10;
<br/>	        y += 10;
<br/>        }
<br/>        if(x == 540 && y == 40 && weight == 40) {
<br/>        	endOfGame = true;
<br/>        }			
<br/>    }
<br/>






Was it clear so far?



Assignments:

1. Modify and run again the SimpleGame class
2. You might not notice any changes as the race condition that might happen in the previous version is a very rare although possible occasion.
| Check Your Progress | Propose QnA | Have a question or comments for open discussion?

Have a suggestion? - shoot an email
Looking for something special? - Talk to me
Read: IT of the future: AI and Semantic Cloud Architecture | Fixing Education
Do you want to move from theory to practice and become a magician? Learn and work with us at Internet Technology University (ITU) - JavaSchool.com.

Technology that we offer and How this works: English | Spanish | Russian | French

Internet Technology University | JavaSchool.com | Copyrights © Since 1997 | All Rights Reserved
Patents: US10956676, US7032006, US7774751, US7966093, US8051026, US8863234
Including conversational semantic decision support systems (CSDS) and bringing us closer to The message from 2040
Privacy Policy