Multithreading: C# vs. Java

In my pervious post I described basic multithreading constructs in C#. Now, I would like to compare them to conforming constructs in Java. It might be useful for those of you, who has already created some multithreaded applications in Java, and would like to learn how to do the same in C#.

Creating a new thread

C#:

using System;
using System.Threading;

class ThreadTest
{
  static void Main()
  {
    Thread t = new Thread (Method);
    t.Start();    
  }
 
  static void Method()
  {
    Console.WriteLine("Thread started");
  }
}

Java:

public class Program {
  public static void main(String[] args) {
    ThreadClass t = new ThreadClass();
    t.start(); 
  }
}
 
class ThreadClass extends Thread {
  @Override
  public void run() {
    System.out.println("Thread started");
  }
}

Waiting for another thread to finish

C#:

using System;
using System.Threading;

class ThreadTest
{
  static void Main()
  {
    Thread t = new Thread (Method);
    t.Start();   
    t.Join(); //wait for thread t
    Console.WriteLine("Created thread finished");
  }
 
  static void Method()
  {
    Console.WriteLine("Started new thread...");
    Thread.Sleep(1000);
    Console.WriteLine("Finishing new thread...");
  }
}

Java:

public class Program {
  public static void main(String[] args) {
    ThreadClass t = new ThreadClass();
    t.start();
    try {
      t.join(); //wait for thread t
      System.out.println("Created thread finished");
	} catch(InterruptedException e) { 
	  // handle exception
	}
    
  }
}
 
class ThreadClass extends Thread  {
  @Override
  public void run() {
    System.out.println("Started new thread...");
    try {
      Thread.sleep(1000);
    } catch(InterruptedException e) {
      // handle exception
    }
    System.out.println("Finishing new thread...");
  }
}

Accessing shared variable

C#:

using System;
using System.Threading;

class ThreadTest
{
  static readonly object locker = new object();
  static int sharedVariable;

  static void Main()
  {
    Thread t = new Thread (Method);
    t.Start();   
    lock(locker)
    {
      // sample operation
      if(sharedVariable==0)
      {
        sharedVariable = 1;
      }
    }
  }
 
  static void Method()
  {
    lock(locker)
    {
      // sample operation
      if(sharedVariable>0)
      {
        sharedVariable++;
      }
    }
  }
}

Java:

public class Program {
  public static int sharedVariable;
  public static final Object lock = new Object();
  public static void main(String[] args) {
    ThreadClass t = new ThreadClass();
    t.start(); 
    synchronized(lock)
    {
      //sample operation
      if(sharedVariable==0) {
        Program.sharedVariable = 1;
      }
    }      
  }
}
 
class ThreadClass extends Thread {
  @Override
  public void run() {
    synchronized(Program.lock) {
      //sample operation
      if(Program.sharedVariable>0) {      
        Program.sharedVariable++;
      }
    }
  }
}

Signaling

C#:

using System;
using System.Threading;

class ThreadTest
{
  static EventWaitHandle _waitHandle = new AutoResetEvent (false);
 
  static void Main()
  {
    new Thread (Waiter).Start();    
    Console.WriteLine("Wait for notification...");
    _waitHandle.WaitOne();
    Console.WriteLine("Notification received.");
  }
 
  static void Waiter()
  {
    Thread.Sleep (1000);
    Console.WriteLine("Sending notification...");
    _waitHandle.Set();
  }
}

Java:

class Program
{ 
  public static void main(String[] args) {
    ThreadClass t = new ThreadClass();
    t.start();
    System.out.println("Wait for notification..."); 
    synchronized(t) {
      try {
        t.wait();
      } catch(InterruptedException e) {
        //handle exception
      }
    }
    System.out.println("Notification received.");
  }
}
 
class ThreadClass extends Thread {
  @Override
  public void run() {
  	try {
      Thread.sleep(1000);
    } catch(InterruptedException e) {
      //handle exception
    }    
    System.out.println("Sending notification...");
    synchronized(this) {
      notify();
    }
  }
}

Summary

As we can see, threading constructs in both languages are very similar.

I put all above code in github repository: Threading-in-CSharp-vs-Java.

Do you think, there are some other fundamental examples, which should be mentioned in this post?