Page 1 of 1

Threads The how and why of threads. Rate Topic: -----

#1 William_Wilson  Icon User is offline

  • lost in compilation
  • member icon

Reputation: 205
  • View blog
  • Posts: 4,807
  • Joined: 23-December 05

Posted 02 June 2007 - 12:17 PM

Java Threads – version 2

*I want to thank 1lacca for his input (viewable in the comments), I have changed the wording in a few sections, as well as adding the definition of ThreadGroups and the basics of Synchronization.
(version 1 is also available as a text file at the end of the tutorial)


Threads are a way to produce parallel code. Instead of running simply top down code, if a thread is created at (example line 4), the code in the thread begins to run, as well as the code at line 5. These two pieces of code begin to run at the same time. There are many uses for threads, but they must be used with care, that unthreaded code is not dependant on threaded code. A complete description of the different ways to use threads will be described, some reasonable applications with examples and then examples where problems can arise.

Using Threads:
The first thing to understand is that when you run a Java application, it is a process. Just like running Notepad, FireFox, etc., they are each a process running under your Operating System and they can run at the same time. Which makes it important to know that a process is a special case of thread, which controls the sub-threads below it. These sub-threads are contained within the same memory, or address space which was allocated to the original process, thus they are able to share code and variables without special commands which are needed to pass information across two processes. The process is also connected to init or the related application, which determines if a process can continue running.
Thus a Java application can create its own threads, which it controls (how it does this is not important for the sake of understanding this tutorial). What is important is that threads running in parallel are not predictable in general, but these parallel segments of code, have the potential to run faster than a completely linear code. If done properly.

In Java a thread is created as a separate class, either within the same class, or a separate class in one of two ways:
Extending class Thread:
public class Threads extends Thread
{
	public void run()
	{
		//thread code
	}
}


Or,
Implementing class Runnable:
public class Threads implements Runnable
{
	public void run()
	{
		//thread code
	}
}


In both cases, the key is the method: public void run().

When a thread is started, the method which is launched automatically is the run() method. Similar to a constructor of a class, when the class is created.

Using the examples above, to create a Thread extending Thread:
Thread t = new Threads();
Creating a Thread with extending Runnable:
Thread t = new Thread(new Threads());

Both of these methods are available since the Thread class implements Runnable itself.
Now that the threads are created, when the code within the run() method is wanted, the thread must be started, using the .start() method:
t.start();
This will work in both cases, as both start the Thread object.

NOTE: A ThreadGroup is a class which contains threads, and/or other ThreadGroups. These groups can be given names, and have many of the properties/methods of a Thread. If no ThreadGroup is explicitly used, all threads are added to a default ThreadGroup.

Many other methods are available, the most useful are:
int activeCount()
Returns the number of active threads, within the same ThreadGroup. There may be more threads above or below this ThreadGroup, which are not counted.

void checkAccess()
This method determines if the current Thread has the right to modify the thread, eg. Variables, calls, etc. This method throws a SecurityException if the Thread is not allowed to be modified.

Thread currentThread()
Returns a reference to the currently running Thread. Care should be taken with this method, if multiple threads are running.

void destroy()
Similar to using the depreciated and unsafe suspend(), except that this Thread will not respond to resume(). According to Java.Sun.com it has never been properly implemented, and is deadlock prone. There may be circumstances where this is a better option, but should be avoided.

void dumpStack()
Prints out a stack trace of the current Thread. Similar to the stack trace of an Exception.

int enumerate(Thread[] tarray)
Copies the active threads of the current ThreadGroup to the supplied array.

boolean holdsLock(Object obj)
Determines if the current thread holds a lock on the Object obj. This becomes important with many threads, or producer/consumer programs, protecting against deadlock.

void interrupt()
Interrupts the current Thread if and only if the Thread is not blocked by another Thread, if the current Thread is blocked, interrupting will cause an Exception to be thrown, and cause the Thread to terminate. To ensure this happens, a global boolean variable thus accessable to all Threads can be used and change it’s value when wanting to stop. This may not stop the Thread if it is loop based, but it has now become blocked, and calling interupt() will stop it immediately. If the Thread was not blocked, this call will set the interrupt status, for use with the following methods.

boolean interrupted()
Returns whether the Thread is currently interrupted. Also clears the interrupted state.

boolean isInterrupted()
Returns whether the Thread is currently interrupted.

boolean isAlive()
Returns if the Thread is alive or not. Eg: started, but not finished yet.

boolean isDaemon()
Returns true if the process is in an infinite loop, or is dependent on a Thread which is in an infinite loop, thus making the Thread a Daemon. Also known as a defunct process in Linux.

void join() or void join(long millis) or void join(long millis, int nanos)
Waits indefinitely, or a supplied length of time, for a Thread to finish. Thus allowing the Threads to “join”.

void setPriority(int newPriority)
Takes a value between 1 and 10, 1 = MIN_PRIORITY, 5 = NORM_PRIORITY, 10 = MAX_PRIORITY. 5 is the default, but priority can be important for background processes, etc.

void sleep(long millis) or void sleep(long millis, int nanos)
Forces a Thread to “sleep” or wait the specified length of time.

void yield()
Temporarily pauses a Thread, to allow other threads to execute.

Examples:
Count Threads:
public class Threads
{
	public int value = 0;
	
	public Threads()
	{
		for(int i=0;i<10;++i)
		{
			new SleepThread().start();
		}
	}
	
	public class SleepThread extends Thread
	{
		public void run()
		{
			try
			{
				sleep(100);
			}
			catch(Exception e)
			{}
		}
	}
	public static void main(String[] args)
	{
		Threads t = new Threads();
		for(int i=0;i<1000;++i)
		{
			System.out.println(Thread.activeCount());
		}
	}
}


This example creates 10 threads, on top of the main method thread. Looping long enough, we run through a count of 11, through 1.

Joining:
public class Threads
{
	Thread thread;
	public Threads()
	{
		thread = new Join();
		thread.start();
	}
	
	private class Join extends Thread
	{
		public void run()
		{
			try
			{
				sleep(10000); //10s sleep
			}
			catch(Exception e)
			{}
		}
	}
	public static void main(String[] args)
	{
		Threads t = new Threads();
		try
		{
			t.thread.join();
			System.out.println("Joined");
		}
		catch(Exception e)
		{}
	}
}


The Thread created sleeps 10 seconds, once it finishes, the main method continues, as the Thread has joined the single stream of code.

Yielding:
public class Threads
{
	Thread thread;
	public Threads()
	{
		thread = new Join();
		thread.start();
	}
	
	private class Join extends Thread
	{
		public void run()
		{
			try
			{
				sleep(10000); //10s sleep
			}
			catch(Exception e)
			{}
		}
	}
	public static void main(String[] args)
	{
		Threads t = new Threads();
		try
		{
			t.thread.yield();
			Thread.sleep(1000); //clear pause
			System.out.println("Yield 1");
			System.out.println("Yield 2");
			System.out.println("Yield 3");
			System.out.println("Yield 4");
			System.out.println("Yield 5");
			System.out.println("Yield 6");
			System.out.println("Yield 7");		}
		catch(Exception e)
		{}
	}
}


This allows the main Thread to continue, until finished, once finished the original Thread continues again.


Interrupting, to stop a (blocked) Thread:
public class Threads2
{
	volatile boolean stopped = false;
	Thread thread;
	
	public Threads2()
	{
		thread = new InterruptThread();
		thread.start();
	}
	
	private class InterruptThread extends Thread
	{
		public void run()
		{
			while(!stopped)
			{
				System.out.println("Thread running");
				try
				{
					Thread.sleep(10000);
				}
				catch(Exception e)
				{
					System.out.println("Thread interrupted");
				}
			}
		}
	}
	
	public static void main(String[] args)
	{
		Threads2 t2 = new Threads2();
		try{
			Thread.sleep(1);
		}
		catch(Exception e)
		{
		}
		t2.stopped = true;
		t2.thread.interrupt();
	}
}


t2.thread.interrupt(); this line if removed will cause the loop in the Thread to finish it’s pass (sleeping 10 seconds) before ending. The loop was blocked with the variable change, so simply passing an interrupt message to it, causes an exception and immediate termination.

Most of the other methods are straight forward, and are used on a less frequent basis.

Reasonable Uses:
If care is taken with multiple threads, as well as using the yield() method properly to force proper threads to finish in the correct order. A perfect example of proper Thread use, is in GUIs. Most users have used a program where an operation takes a long time, and the GUI stalls: buttons stay depressed, perhaps goes all white, or even gives the classic “(not responding)” message. A simple threading of the button action will correct this entirely.

An example of an unthreaded GUI with a long (infinite) task:
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JButton;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class Threads
{
	JButton jb;
	public Threads()
	{
		JFrame jf = new JFrame();
		jf.getContentPane().add(new Display());
		jf.setTitle("GUI");
		jf.setResizable(true);
		jf.setLocation(100,100);
				jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
				jf.setSize(200,200);
				jf.setVisible(true);
				
				jb.addActionListener(new ButtonEvent());

	}
	
	private class Display extends JPanel
	{
		public Display()
		{
			jb = new JButton("button");
			add(jb);
		}
	}
	
	private class ButtonEvent implements ActionListener
	{
		public void actionPerformed(ActionEvent e)
		{
			while(true)
			{	
			}
		}
	}
	public  static void main(String[] args)
	{
		New Threads();
	}
}


The button stops, as well as the application in general, in fact it needs to be terminated.

A simple Thread fixes the entire problem. The button can even be pressed again. It is up to the programmer to handle this operation, perhaps disable the button, or have the new operation yield() to the old one. Another option is to create single instances of the threads, thus they are only started, and not created.
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JButton;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class Threads
{
	JButton jb;
	public Threads()
	{
		JFrame jf = new JFrame();
		jf.getContentPane().add(new Display());
		jf.setTitle("GUI");
		jf.setResizable(true);
		jf.setLocation(100,100);
				jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
				jf.setSize(200,200);
				jf.setVisible(true);
				
				jb.addActionListener(new ButtonEvent());

	}
	
	private class Display extends JPanel
	{
		public Display()
		{
			jb = new JButton("button");
			add(jb);
		}
	}
	
	private class ButtonEvent implements ActionListener
	{
		public void actionPerformed(ActionEvent e)
		{
			new ButtonThread().start();
		}
		
		private class ButtonThread extends Thread
		{
			public void run()
			{
				while(true)
				{	
				}
			}
		}
	}
	public  static void main(String[] args)
	{
		New Threads();
	}
}


*NOTE depending on what this button does, it could become extremely important that these threads are handled by the programmer, and not allowed to run free, as this example allows. Several suggestions of how to handle these threads were supplied above.

Problems with Threads:
The main problem with threads is that the threads are running at the same time:
public class Threads
{
	public int value = 0;
	public Threads()
	{
		new aThread1().start();
	}
	
	private class aThread1 extends Thread
	{
		public void run()
		{
			for(int i=0;i<10;++i)
			{
				System.out.print("");
			}
			value = 1;
		}
	}
	public static void main(String args[])
	{
		Threads t = new Threads();
for(int i=0;i<1000;++i)
		{
			System.out.print("");
		}
		System.out.println(t.value);
		t.value = 2;
		System.out.println(t.value);
}
}


This code when run will regularly give the result:
1
2
If it is run 15 or 20 times however, you will be surprised by a result of:
0
2
It cannot be assumed which thread will run fastest, and since the “unthreaded” results are dependent on the threaded parallel code.
This example shows a realistic situation where both cases have for loops, where one loop runs faster than the other.

This is why full testing is important, and whether it seems necessary or not, all threads should be handled carefully, blocking and yielding when threads are dependent on each other. Threads are most useful when they are unrelated, and allow multiple blocks of code to be completed at the same time.

Synchronization:
The entire Thread is not likely to be synchronized, but rather it is a method representing a segment of code which must be synchronized to all Threads.

Synchronization is supported in two types:
Mutual Exclusion: Implemented with Object locks. Allowing multiple threads to run independently on shared data, with the ability to lock each other to prevent conflicts.

Cooperation: Implemented with the wait() and notify() methods of class Object. This method of synchronization is meant to be used when all all threads work towards a single result.

It is important to understand synchronization locks. When a Thread wishes to run code which is synchronized it must have the lock. Having the lock essentially means that no other Thread may run the synchronized code. Once the current Thread finishes with the synchronized code, it releases the lock and allows another Thread to run the synchronized code.
This effectively allows code to run in parallel as long as they do not cause a conflict on another Thread. The code placed in the synchronize method is that which may cause such a conflict.

Implementing the syncronized code is simple. It is a special block of code within a method:
	public void aMethod()
	{
		synchronized(variable)
		{
			
		}
	}


Where variable is an Object which must not be modified by any other synchronized Thread.
Or as a method declaration:
	public synchronized void anotherMethod()
	{
		
	}


Where this method will aquire a lock for it’s containing class, as no Object is supplied.

NOTE: A non-synchronized method, may modify variables, while a synchronized method has a lock on this variable’s containing Object. Also take care with inheritence as sychronization is not inherited.

As with Threads themselves synchronization has it’s downfalls. Due to the potential for deadlock. Java has implemented ways to avoid this, by allowing a synchronized method to call another, even if they both require a lock on the same Object.
public class Threads2
{	
	public Threads2()
	{
		thread1 = new Thread1();
		thread2 = new Thread1();
		thread1.start();
		thread2.start();
	}
	
	private class Thread1 extends Thread
	{
		public void run()
		{
			anotherMethod();
		}
	}
public synchronized void anotherMethod()
	{
		{
			System.out.println("Entering Synchronized Code");
			try{Thread.sleep(10000);}catch(Exception e){}
		}
	}
	public static void main(String[] args)
	{
		New Threads2();
	}
}


Note that there is a 10 second wait between displaying the first line and the second. Yet if the anotherMethod() is made non-synchronized, they both appear at once, since there is no restriction on the threads in parallel.

When objects are waiting to execute, do to a lock and synchronized code, this is known as either: entering the monitor, or entering the wait queue. Both terms are common as once the Thread is waiting, it has both become a monitor, which is waiting for signals, and waiting for the current locked Thread to finish.
If the current Thread requires an operation by another Thread to complete before continuing, you can reorder the wait queue, by calling wait(long timeout) on the running Thread. This exmaple has thread1 wait until a variable is set by thread2.
public class Threads2
{
	volatile boolean stopped = false;
	Thread thread1,thread2;
	
	public Threads2()
	{
		thread1 = new Thread1();
		thread2 = new Thread2();
		thread1.start();
		thread2.start();
	}
	
	private class Thread1 extends Thread
	{
		public synchronized void run()
		{
			try
			{
				while(!stopped)
				{
					wait(1);
				}
			}
			catch(Exception e)
			{
				System.out.println("Error");
			}
			System.out.println("Thread 1 Waited");
		}
	}
	
	private class Thread2 extends Thread
	{
		public synchronized void run()
		{
			System.out.println("Entering: Thread 2");
			try{sleep(500);}catch(Exception e){}
			stopped = true;
		}
	}
	public static void main(String[] args)
	{
		New Threads2();
	}
}


The other option is to use a constant wait(), which waits until the notify() or notifyAll() method is called to release the wait on a specific Object, it can be any Object a Java supplied or your own.
*On a side note, the Java documentation on wait() and notify() is horrible, and finding examples on java.sun is almost imposisble. This is a simple example which can easily be expanded.
public class Threads2
{
	Thread thread1,thread2;
	private Object lock = new Object();
	
	public Threads2()
	{
		thread1 = new Thread1();
		thread2 = new Thread2();
		thread1.start();
		thread2.start();
	}
	
	private class Thread1 extends Thread
	{
		public void run()
		{
			synchronized(lock)
			{
				try
				{
					lock.wait();
				}
				catch(Exception e)
				{
					System.out.println("Error");
				}
				System.out.println("Thread 1 Waited");
			}
		}
	}
	
	private class Thread2 extends Thread
	{
		public void run()
		{
			System.out.println("Entering: Thread 2");
			try{sleep(500);}catch(Exception e){}
			synchronized(lock)
			{
				//something which must be done before thread1 finishes
				lock.notify();
			}
		}
	}


This can be done a little more dynamically as well:
public class Threads2
{
	volatile boolean stopped = false;
	Thread thread1,thread2;
	private Object lock = new Object();
	
	public Threads2()
	{
		thread1 = new Thread1();
		thread2 = new Thread2();
		thread1.start();
		thread2.start();
	}
	
	private class Thread1 extends Thread
	{
		public void run()
		{
			synchronized(lock)
			{
				try
				{
					if(!stopped)
						lock.wait();
				}
				catch(Exception e)
				{
					System.out.println("Error");
				}
				System.out.println("Thread 1 Waited");
			}
		}
	}
	
	private class Thread2 extends Thread
	{
		public void run()
		{
			System.out.println("Entering: Thread 2");
			try{sleep(500);}catch(Exception e){}
			synchronized(lock)
			{
				//something which must be done before thread1 finishes
				if(!stopped)
				{
					stopped = true; //free any other dependencies
					lock.notify();
					stopped = false; //reset incase this thread is called again
				}
			}
		}
	}
	public static void main(String args[])
	{
		New Threads2();
	}
}



Hopefully you not only understand how to use threads, but where and why to use them, also the idea behind handling these threads to ensure the proper order of completion on dependent threads.

Attached File  Threads_Tutorial_version_1.txt (11.49K)
Number of downloads: 480

Is This A Good Question/Topic? 3
  • +

Replies To: Threads

#2 skyhawk133  Icon User is offline

  • Head DIC Head
  • member icon

Reputation: 1875
  • View blog
  • Posts: 20,282
  • Joined: 17-March 01

Posted 02 June 2007 - 01:31 PM

Great tutorial William.


Vote for it here: http://www.dzone.com...ds_in_java.html
Was This Post Helpful? 0
  • +
  • -

#3 1lacca  Icon User is offline

  • code.rascal
  • member icon

Reputation: 44
  • View blog
  • Posts: 3,822
  • Joined: 11-August 05

Posted 03 June 2007 - 06:06 AM

Nice start, but I have to make some comments :)
First of all, I'm not sure but in many literature the main difference between processes and threads is that threads use the same memory as their parenst, so this means that they share the variables. Processes on the other hand have their own memory, so if you want to access a variable in another process you must use interprocess communication. I think it is good to distinguish right at the beginning, because this will help the understanding of many things later a lot.

Quote

Thus a Java application can create its own threads, which it controls (how it does this is not important). What is important is that threads running in parallel are not predictable in general, but code running in parallel is faster.


I think this was for the sake of simplicity, but this is a dangerous oversimplification of this topic. Some tasks can be accelerated by parallelization, some can not. I've seen some applications where people tried to parallelize, and it had disastrous effects on performance. This is something that needs a lot of thinking in advance, and experience is really needed.

Quote

int activeCount()
Returns the number of active threads, under the current Thread.

Not really under this thread, but in the ThreadGroup this Thread belongs to - more like on the thread's "level".

View PostWilliam_Wilson, on 2 Jun, 2007 - 09:17 PM, said:

void destroy()
A better option to using stop(). Stops the Thread, without destroying any data which may affect the state or running time of other Threads. All data is removed after all threads finish.

Not really a better option, since it is deprecated. From the Java API:

Quote

Deprecated. This method was originally designed to destroy this thread without any cleanup. Any monitors it held would have remained locked. However, the method was never implemented. If if were to be implemented, it would be deadlock-prone in much the manner of suspend(). If the target thread held a lock protecting a critical system resource when it was destroyed, no thread could ever access this resource again. If another thread ever attempted to lock this resource, deadlock would result. Such deadlocks typically manifest themselves as "frozen" processes. For more information, see Why are Thread.stop, Thread.suspend and Thread.resume Deprecated?.


View PostWilliam_Wilson, on 2 Jun, 2007 - 09:17 PM, said:

int enumerate(Thread[] tarray)
Copies the active threads into the supplied array.

The active threads only from this thread's ThreadGroup.

View PostWilliam_Wilson, on 2 Jun, 2007 - 09:17 PM, said:

void interrupt()
Interrupts the current Thread if and only if the Thread is not blocked by another Thread, effectively ending the Thread.

Again, dangerous oversimplification. This method works in a much diverse way. Let me quote the API again:

Quote

Unless the current thread is interrupting itself, which is always permitted, the checkAccess method of this thread is invoked, which may cause a SecurityException to be thrown.

If this thread is blocked in an invocation of the wait(), wait(long), or wait(long, int) methods of the Object class, or of the join(), join(long), join(long, int), sleep(long), or sleep(long, int), methods of this class, then its interrupt status will be cleared and it will receive an InterruptedException.

If this thread is blocked in an I/O operation upon an interruptible channel then the channel will be closed, the thread's interrupt status will be set, and the thread will receive a ClosedByInterruptException.

If this thread is blocked in a Selector then the thread's interrupt status will be set and it will return immediately from the selection operation, possibly with a non-zero value, just as if the selector's wakeup method were invoked.

If none of the previous conditions hold then this thread's interrupt status will be set.

Interrupting a thread that is not alive need not have any effect.


So what it really means, is that in a blocking situation, usually an exception is raised. In other cases the interrupted flag is set, and nothing else happens. The thread won't stop. You have to check the interrupted flag yourself, and quit.

View PostWilliam_Wilson, on 2 Jun, 2007 - 09:17 PM, said:

boolean interrupted() or boolean isInterrupted()
Returns whether the Thread is currently interrupted. Also clears the interrupted state.

These are not the same! The interrupted function clears the thread's interrupted flag, the isInterrupted doesn't.

View PostWilliam_Wilson, on 2 Jun, 2007 - 09:17 PM, said:

This is why full testing is important, and whether it seems necessary or not, all threads should be handled carefully, blocking and yielding when threads are dependent on each other.

The main problem is that with threads it is impossible to do full testing. There are too much possibilities due to timing and architectures, and even JVM implementations (and even JVM command line options). The best way to start using threads is checking existing design patterns, because they give very good ideas and usually a deeper understanding of the problem.

So I've touched the thread stopping problem. A very good resource is available here.

I also miss a bit synchronization from this tutorial, which is a very important thing when dealing with threads, however can cause serious slowdowns in multiprocessor systems.

Anyway, sorry William for the messing, but this is one of my favorite topics in Java and general programming theory, so I thought that some of the thigns had to be a bit deeper explained.

This post has been edited by 1lacca: 03 June 2007 - 06:08 AM

Was This Post Helpful? 0
  • +
  • -

#4 William_Wilson  Icon User is offline

  • lost in compilation
  • member icon

Reputation: 205
  • View blog
  • Posts: 4,807
  • Joined: 23-December 05

Posted 03 June 2007 - 07:15 AM

I'm always willing to take critisism good or bad.

-The address space of a process is seperate, and threads will be within it it's true, suppose that may have been a good thing to mention.

int activeCount():
just bad wording on my part, i will edit my copy to ammend this.

void destroy():
suppose my API documentation must be an older version, as it was not listed as depreciated, but rather, stop() had been depreciated, and this was thus the only way to effectively stop a thread immediately.

int enumerate(Thread[] tarray):
again bad wording, to be consistent, i will fix this as well... perhaps i will go more indepth about Thread groups as well.

void interrupt():
has always had the effect of ending a Thread when i've used it, perhaps it was a fluke? I will look into this more in depth.
Forcing a null Thread is a good suggestion from Java.Sun, I have regularly used a while(variable) loop, by setting variable to false, the loop is blocked, and thus so is the Thread. Perhaps i will add a small example.

boolean interrupted() or boolean isInterrupted():
The difference i did not know, i appreaciate being filled in :)

Sync:
I was at a toss up of how to approach this tutorial, Threads are a reasonably complex topic, yet, I wanted average Java coders to not be afraid to attempt using them. Perhaps you are right and I should have included it. Once I have made these changes, I will attatch a text file with the updated version to the tutorial. I appreciate your input 1lacca, my OS course this year focussed on the threoretical of threads and processes mostly, and i have learned that understanding and explaining threads are 2 completely different things, lol
Was This Post Helpful? 0
  • +
  • -

#5 1lacca  Icon User is offline

  • code.rascal
  • member icon

Reputation: 44
  • View blog
  • Posts: 3,822
  • Joined: 11-August 05

Posted 03 June 2007 - 11:25 AM

View PostWilliam_Wilson, on 3 Jun, 2007 - 04:15 PM, said:

I'm always willing to take critisism good or bad.

That's a really good virtue!

View PostWilliam_Wilson, on 3 Jun, 2007 - 04:15 PM, said:

void interrupt():
has always had the effect of ending a Thread when i've used it, perhaps it was a fluke? I will look into this more in depth.
Forcing a null Thread is a good suggestion from Java.Sun, I have regularly used a while(variable) loop, by setting variable to false, the loop is blocked, and thus so is the Thread. Perhaps i will add a small example.


Yes, it is a common belief, since for threads that are blocked, and the appropiate exception is not handled, that is the outcome. That is why it is important to know (and stress), that in a situation, where you are making calculations or other things that fall into the other category, the thread just won't stop.

View PostWilliam_Wilson, on 3 Jun, 2007 - 04:15 PM, said:

Sync:
I was at a toss up of how to approach this tutorial, Threads are a reasonably complex topic, yet, I wanted average Java coders to not be afraid to attempt using them. Perhaps you are right and I should have included it. Once I have made these changes, I will attatch a text file with the updated version to the tutorial. I appreciate your input 1lacca, my OS course this year focussed on the threoretical of threads and processes mostly, and i have learned that understanding and explaining threads are 2 completely different things, lol


Yes, I was thinking a bit about bringing this thing here, but I am confident, that it is better at least to mention, that parallelism just can not be separated from concurrent modification of variables (and the dangers in it). It makes this topic maybe longer, and harder to understand, but without this knowledge it is kind of a suicide to start using threads :o

I know theoretical courses, and I like them. However none of them can give a complete view of a topic (especially like this) that is quite hard for the human brain to grasp in action. I had an instructor, who had a quote: "one lesson in practice is worth 10 in theory", of course practice can be really so useful, only if you know enough theory in advance ;)

I am really glad, that you didn't took my criticism as nitpicking, and I think that you did a very good job on this very complex topic!
Was This Post Helpful? 0
  • +
  • -

#6 William_Wilson  Icon User is offline

  • lost in compilation
  • member icon

Reputation: 205
  • View blog
  • Posts: 4,807
  • Joined: 23-December 05

Posted 03 June 2007 - 09:39 PM

I do understand sync at a moderate to advanced level I believe, and I am in the process of adding at least the basics of why it's important for Threads right now. There is lots of room for an advanced tutorial covering it completely, but you're right, it should have been there to show how to better avoid the conflicts of Dependent Threads.

I did some digging on the interrupt() method, and discovered how to ensure a blocked thread when required, and the difference between an unblocked code.

knowing the theory, seems to mean more only after you've done it in practice. The here's why it did what it did, kind of result :)

and finally thanks for both compliments. I've always been of the opinion, that if everyone told me what i did was perfect and wonderful, there'd be no point in expanding what i know on the subject, which is what I have done here, and gone more in depth on a few topics, whether it all shows in the tutorial or not, it makes a difference to me. :)
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1