5. Is That Thread Safe?
package com.thread;
class ApplicationThread implements Runnable{
private int i = 0;
@Override
public void run() {
System.out.println(++i);
}
}
public class Main {
public static void main(String[] args) {
for (int i = 0; i < 1000; i++)
{
Thread thread1 = new Thread(new ApplicationThread());
thread1.start();
}
}
}
6. Is That Thread Safe?
package com.thread;
class ApplicationThread implements Runnable{
private int i = 0;
@Override
public void run() {
System.out.println(++i);
}
}
public class Main {
public static void main(String[] args) {
Runnable runnable = new ApplicationThread();
for (int i = 0; i < 100000; i++)
{
Thread thread1 = new Thread(runnable);
thread1.start();
}
}
}
10. Compilers optimization
• Constant folding
Ex:
static final int length = 25;
static final int width = 10;
int res = length * width; //int res = 250;
• Drop memory write for non volatile variables
• Instructions Reordering
• int A, B; • int A, B;
• void foo() • void foo()
• { A = B + 1; • {B = 0;
• B = 0; } • A = B + 1; }
For more Reference, Cglib (Code generation Library)
11. Illustrative Example
public class NoVisibility
{
private static boolean ready;
private static int number;
private static class ReaderThread extends Thread
{
public void run()
{
while (!ready)
Thread.yield();
System.out.println(number);
}
}
public static void main(String[] args)
{
new ReaderThread().start();
number = 42;
ready = true;
}
}
12. Solution
public class NoVisibility
{
private static volatile boolean ready;
private static volatile int number;
private static class ReaderThread extends Thread
{
public void run()
{
while (!ready)
Thread.yield();
System.out.println(number);
}
}
public static void main(String[] args)
{
new ReaderThread().start();
number = 42;
ready = true;
}
}
20. Java Concurrency Problems
and Symptoms
Invalid States
Stale values (old values, other threads values)
Null pointer exceptions
Array out of bound exceptions
Symptom
Code works in Debugging while not working in the
running mode or production mode
Working with JVM vendor while not working with
other
Working with certain usage load and doesn’t work
when the usage is increased (JIT Compiler)
23. Thread confinement
(Not to share)
If data is only accessed from a single
thread, no synchronization is needed.
JDBC Connections , confines the connection
for a single thread
Implementation using ThreadLocal
24. Thread Confinement
public class ConnectionDispenser {
private static class ThreadLocalConnection extends ThreadLocal {
public Object initialValue() {
return DriverManager.
getConnection(ConfigurationSingleton.getDbUrl());
}
}
private static ThreadLocalConnection conn = new
ThreadLocalConnection();
public static Connection getConnection() {
return (Connection) conn.get();
}
}
25. Stack Confinement
Not to share
Object can only reached using local
variables.
Widely used in our projects
public class Income extends HttpServlet {
@override
protected void doPost(HttpServletRequest request, HttpServletResponse response) {
try
{
IncomeForm income = Util.jsonToObject(input, IncomeForm.class);
26. Immutable
Fieldsare Final , values are set only from
the constructors, (this reference does not
escaped)
Immutable V effectively Immutable (Fields
are not declared final, but there are not
setters methods )
Volatile Reference to Immutable Objects
27. Illustrative example
@Immutable
class OneValueCache {
private final BigInteger lastNumber;
private final BigInteger[] lastFactors;
public OneValueCache(BigInteger i,
BigInteger[] factors) {
lastNumber = i;
lastFactors = Arrays.copyOf(factors, factors.length);
}
public BigInteger[] getFactors(BigInteger i) {
if (lastNumber == null !lastNumber.equals(i))
return null;
else
return Arrays.copyOf(lastFactors, lastFactors.length);
}
}
28. Using volatile to publish
immutable objects
@ThreadSafe
public class VolatileCachedFactorizer implements Servlet {
private volatile OneValueCache cache =
new OneValueCache(null, null);
public void service(ServletRequest req, ServletResponse resp) {
BigInteger i = extractFromRequest(req);
BigInteger[] factors = cache.getFactors(i); //Tip !!!
if (factors == null) {
factors = factor(i);
cache = new OneValueCache(i, factors);
}
encodeIntoResponse(resp, factors);
}
}
30. Synchronized
class SynchronizedCounter {
private int c = 0;
public synchronized void increment() {
c++;
}
public synchronized void decrement() {
c--;
}
public synchronized int value() {
return c;
}
}