Threading in Java

import java.util.Random;

public class ThreadTutorial {
	
	static class ThreadClass1
	{
		boolean stop = false;
		void DoSomething()
		{
			Random r = new Random();
			r.nextInt();
		}
		
		public synchronized void thinking() 
		{
			DoSomething();
			
			System.out.println("thinking for 2 seconds");
			try {
				Thread.sleep(2000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		public synchronized void reading()
		{
			DoSomething();
			
			System.out.println("reading for 1 seconds");
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		
		public ThreadClass1()
		{
			Thread t1 = new Thread(new Runnable() {
				@Override
				public void run() {
					while(true)
					{
						thinking();
						if(stop != false)
							break;
					}
				}
			});
			t1.start();
			
			Thread t2 = new Thread(new Runnable() {
				@Override
				public void run() {
					while(true)
					{
						reading();
						if(stop != false)
							break;
					}
				}
			});
			t2.start();
			
			try {
				Thread.sleep(60000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			stop = true;
			
			try {
				t1.join();
				t2.join();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
	
	static class ThreadClass2
	{
		boolean stop = false;
		Object o1 = new Object();
		Object o2 = new Object();
		
		void DoSomething()
		{
			Random r = new Random();
			r.nextInt();
		}
		
		public void readingHarddrive() 
		{
			DoSomething();
			
			synchronized (o1) {
				System.out.println("reading hard drive for 2 seconds");
				try {
					Thread.sleep(2000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
		public void writingHarddrive()
		{
			DoSomething();
			
			synchronized (o1) {
				System.out.println("writing hard drive for 1 seconds");
				try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}	
			}
		}

		public void readingDatabase() 
		{
			DoSomething();
			
			synchronized (o2) {
				System.out.println("reading database for 5 seconds");
				try {
					Thread.sleep(5000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}	
			}
		}
		public void writingDatabase()
		{
			DoSomething();
			
			synchronized (o2) {
				System.out.println("writing database for 4 seconds");
				try {
					Thread.sleep(4000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}				
			}
		}
		
		public ThreadClass2()
		{
			Thread t1 = new Thread(new Runnable() {
				@Override
				public void run() {
					while(true)
					{
						readingDatabase();
						if(stop != false)
							break;
					}
				}
			});
			t1.start();
			
			Thread t2 = new Thread(new Runnable() {
				@Override
				public void run() {
					while(true)
					{
						writingDatabase();
						if(stop != false)
							break;
					}
				}
			});
			t2.start();
			
			Thread t3 = new Thread(new Runnable() {
				@Override
				public void run() {
					while(true)
					{
						readingHarddrive();
						if(stop != false)
							break;
					}
				}
			});
			t3.start();
			
			Thread t4 = new Thread(new Runnable() {
				@Override
				public void run() {
					while(true)
					{
						writingHarddrive();
						if(stop != false)
							break;
					}
				}
			});
			t4.start();
			
			try {
				Thread.sleep(60000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			stop = true;
			
			try {
				t1.join();
				t2.join();
				t3.join();
				t4.join();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
	public static void main(String[] args) throws InterruptedException {
		new ThreadClass1();
		System.out.println("------------------------------------------------------");
		new ThreadClass2();
	}
}