Tampilkan postingan dengan label will. Tampilkan semua postingan
Tampilkan postingan dengan label will. Tampilkan semua postingan

How will you go about explaining the following Java concepts to a beginner

Minggu, 09 Februari 2014



Q. How will you go about explaining the following Java concepts to a beginner who is starting to learn Java
A.

1. Process Vs Threads
2. Heap versus Stack
3. Local variables versus instance variables
4. How do threads communicate with each other?
5. Are Java methods reentrant?
6. Does Java support recursive method calls?
7. Object creation and Garbage collection
8. Can you garbage collect objects that have a circular reference?
9. Producer-consumer design pattern.


The best way to do this is to write some basic code and then have a pictorial representation as to how the objects are created, how do threads work and communicate with each other, and what is stored in a heap and what is stored in a stack, etc.

Here is an example of a producer thread (thread-0) producing by incrementing the counter from 0, and the consumer thread (i.e. thread-1) consumes by decrementng the counter. These two user created threads are spawned by the main thread, which is created by the JVM and is alwyas there by default. The ConsumerProducer is the shared object with synchronized methods that commuincate with each other via wait( ) and notifyAll methods. Only one of the two synchronized methods can be executed at a time. The wait( ) call in consume( ) relinquishes the lock to the produce( ) method, and once the produce method has incremented the count, it notifies all threads and one of the waiting threads will resume. In this example, there is only one waiting consumer (i.e. Thread-1) thread. So, both threads will be communicating with each other via the wait( ) and notifyAll( ) calls in the shared object ConsumerProducer. This is an example of the producer-consumer design pattern.



Firstly, look at the code and then the diagram. The diagram is simplified to get an understanding and should not be construed as exactly what happens in the JVM.


public class ConsumerProducer {

private int count;

public synchronized void consume() {
while (count == 0) { // keep waiting if nothing is produced to consume
try {
wait(); // give up lock and wait
} catch (InterruptedException e) {
// keep trying
}
}

count--; // consume
System.out.println(Thread.currentThread().getName() + " after consuming " + count);
}

public synchronized void produce() {
count++; //produce
System.out.println(Thread.currentThread().getName() + " after producing " + count);
notifyAll(); // notify waiting threads to resume
}

}


The main thread spawns a consumer and a producer thread. The ConsumerProducer is shared between two threads. The boolean flag is used to signal if it is a consumer thread or a producer thread to invoke the relevant methods.


public class ConsumerProducerTest implements Runnable {

boolean isConsumer;
ConsumerProducer cp;

public ConsumerProducerTest(boolean isConsumer, ConsumerProducer cp) {
this.isConsumer = isConsumer;
this.cp = cp;
}

public static void main(String[] args) {
ConsumerProducer cp = new ConsumerProducer(); //shared by both threads to communicate

Thread producer = new Thread(new ConsumerProducerTest(false, cp));
Thread consumer = new Thread(new ConsumerProducerTest(true, cp));

producer.start();
consumer.start();

}

@Override
public void run() {
for (int i = 1; i <= 10; i++) {
if (!isConsumer) {
cp.produce();
} else {
cp.consume();
}
}

//try with introducing a sleep for 100ms.

}
}

The output will vary, but the last thing consumed will be 0
Thread-0 after producing 1
Thread-0 after producing 2
Thread-0 after producing 3
Thread-0 after producing 4
Thread-0 after producing 5
Thread-0 after producing 6
Thread-0 after producing 7
Thread-0 after producing 8
Thread-0 after producing 9
Thread-0 after producing 10
Thread-1 after consuming 9
Thread-1 after consuming 8
Thread-1 after consuming 7
Thread-1 after consuming 6
Thread-1 after consuming 5
Thread-1 after consuming 4
Thread-1 after consuming 3
Thread-1 after consuming 2
Thread-1 after consuming 1
Thread-1 after consuming 0




The above code can be diagramatically represented as shown below.




  • The JVM is a process. As you could see in the diagram above that each thread has its own stack, but share the same heap space. One heap space per process.

  • The local variables like producer, cp, and consumer are stored in the stack along with the method calls like main( ), run( ), etc.

  • The objects are created in the heap. For example, 2 instances of ConsumerProducerTest and a single instance of ConsumerProducer. Unless the methods of these instances are properly managed, multiple threads can concurrently access these intsnaces to cause thread-safety issues.

  • There are scenarios where the threads want to commuincate with each other. For example, a worker thread produces something and a consumer thread consumes what the producer thread consumed. This can be achieved through thread coordination with the wait and notify( ) / notifyAll( ) methods. In the above example, since both the produce( ) and consume( ) methods of the object ConsumerProducer are synchronized, only one thread can execute either one of the methods. If the count == 0, the consumer thread relinquishes the lock by invoking the wait( ) method and waits for it to be notified again to resume. The producer thread will increment the counter and then will notify all the waiting threads via the notifyAll( ) method. One of the waiting threads will then be able to resume from its waiting state.

  • The local variable isConsumer is used to differentiate between a consumer thread and a producer thread.

  • The count is an instance variable shared by both the consumer and producer thread in a thread-safe manner.



Here are the points that answers the above questions.

  • Each time an object is created in Java it goes into the area of memory known as heap.
  • The primitive variables like int, double, etc are allocated in the stack if they are local variables and in the heap if they are instance variables (i.e. fields of a class).
  • Java is a stack based language and local variables are pushed into stack when a method is invoked and stack pointer is decremented when a method call is completed.
  • In a multi-threaded application, each thread will have its own stack but will share the same heap. This is why care should be taken in your code to avoid any concurrent access issues in the heap space.
  • The stack is thread-safe because each thread will have its own stack with say 1MB RAM allocated for each thread but the heap is not thread-safe unless guarded with synchronization through your code. The stack space can be increased with the –Xss option.
  • All Java methods are automatically re-entrant. It means that several threads can be executing the same method at once, each with its own copy of the local variables.
  • A Java method may call itself without needing any special declarations. This is known as a recursive method call. Given enough stack space, recursive method calls are perfectly valid in Java though it is tough to debug. Recursive methods are useful in removing iterations from many sorts of algorithms. All recursive functions are re-entrant but not all re-entrant functions are recursive.
  • Idempotent methods are methods, which are written in such a way that repeated calls to the same method with the same arguments yield same results.
  • Each time an object is created in Java, it goes into the area of memory known as heap. The Java heap is called the garbage collectable heap. The garbage collection cannot be forced. The garbage collector runs in low memory situations. When it runs, it releases the memory allocated by an unreachable object. The garbage collector runs on a low priority daemon (i.e. background thread). You can nicely ask the garbage collector to collect garbage by calling System.gc( ) but you can’t force it.
  • An object’s life has no meaning unless something has reference to it. If you can’t reach it then you can’t ask it to do anything. Then the object becomes unreachable and the garbage collector will figure it out. Java automatically collects all the unreachable objects periodically and releases the memory consumed by those unreachable objects to be used by the future reachable objects.
  • If two objects have circular reference with each other in the heap, but none of them are reachable from any thread, then those circular referenced objects can be garbage collected.
Read More..

Fedora and Gnome 3 Ubuntu and Unity will openSUSE and KDE benefit

Jumat, 07 Februari 2014

Right now it seems like some of the top Linux distributions such as Fedora and Ubuntu are heading down a slippery slope.

Fedora 15 will be based on Gnome 3, it is still early days for the Gnome 3 project and over time I am confident it will get better but many (including myself) feel its not ready for use.

I believe the simplicity of Gnome 2.x is what made it a success, the main menu bar provided a quick and efficient method of accessing your applications / system settings. The ability to minimize to a panel also provided users with a quick and efficient method of accessing minimized programs and by its very nature visually indicated that a program has been minimized.

Gnome 3 on the other hand doesn’t really have a place to minimize applications to and should you use the gnome tweak tool to enable the minimize button to application windows, applications disappear (not minimize) to the activities tab leaving the user with no apparent visual indicator that an application has been banished (minimised) to the activities tab.

Accessing or viewing applications in Gnome 3 generally requires use of the activities tab where you can either browse through all your applications or search for an application. Unfortunately the Gnome 2.x method of using the main menu (a concept featured in all major operating systems) is still a quicker and more efficient method of accessing your applications. The search function works effectively, although it doesnt help if you dont know what you are searching for.

There is also space in the activities tab to place some of your favorite applications in a dock like fashion which will certainly mitigate some of the inefficiency caused by the method of browsing through or searching for applications, but some will always find it a slight annoyance since you have to invoke the activities tab to view it.

People moved away from the command line and into graphical user interfaces because it made doing things easier and quicker, the current implementation of Gnome 3 compared to Gnome 2.x therefore seems like a step in the wrong direction.

However, visually speaking Gnome 3 looks very modern and stylish.

With Fedora being a project that aims to lead the advancement of FOSS the decision to include bleeding edge software and the latest developments such as Gnome 3 is the right decision and inline with the project goals.

Fedora users will be familiar with the possibility that the latest and greatest can sometimes have a detrimental consequence and for many Gnome 3 is no exception. But the sad reality in this instance is for many Fedora users Gnome 3 is unworkable.

So what will these users do? 

I expect many to hop over to another distro that still features Gnome 2.x and come back at a later date providing Gnome 3 has improved. Alternatively, Fedora does have a few other spins but Fedora at heart has always been a Gnome distribution and the majority of its users Gnome users.

What about Ubuntu?

Taking a look at Ubuntu presents a similar situation. Canonical Ltd have recognized that Gnome 3 is not quite ready for the Ubuntu user base and their solution is Unity. Ubuntu 11.04 features the new Unity desktop from Canonical Ltd which is currently a mish mash of Gnome 2.x and Compiz.

Just like Gnome 3, some users like it and others hate it. Quite clearly Unity is not a finished product and I cannot understand why it was decided to make Unity the default desktop in Ubuntu 11.04.

Some users feel Unity is easy to use and if you rarely ever have to go beyond the dock that stands to follow but just like Gnome 3 it also lacks the application menu as featured in Gnome 2.x. A poor decision.

Instead you can view all applications by using the applications tab or the search function, this is the same as Gnome 3.

The simplicity Gnome 2.x provided Ubuntu users has been lost with Unity, the very simplicity that made Ubuntu easier to use.

Personally I think Unity for Ubuntu is a lost cause. There is nothing wrong with trying out new ideas and I give credit to Canonical Ltd for trying but those who are not good at using computers or those who find slick looking 3D GUIs complicated and hard to navigate will not appreciate Unity.

I feel Canonical Ltd have over looked how the simplicity of Gnome 2.x contributed to making Ubuntu easy to use.

So what now for Ubuntu and Fedora users?

If you are one of those users who likes to have the latest version of a distribution the future may be looking quite grim. It has been confirmed that Ubuntu 11.10 will not feature a classic Gnome 2.x interface and future versions of Fedora will have Gnome 3.

Looking ahead, Unity in Ubuntu 11.10 and Gnome 3 in Fedora 16 may be a completely different experience from what we are seeing right now but nothing is for certain. Therefore due to that uncertainty some users may go about looking for another distribution that doesnt use Gnome 3 or is not Ubuntu with Unity.

The quest for another distribution will inevitably spark interest in some of the other desktop environments available and speaking of desktop environments, is there anything worth mentioning over KDE 4.6.x?

Will openSUSE therefore benefit?

With the recent acquisition of Novell by Attachmate now complete, SUSE has been split away from Novell and will be established as its own corporate entity. A positive step in the right direction for SUSE and the openSUSE project.

Despite my own reasons for putting openSUSE behind me, it has the best implementation of KDE 4.6 (although I maintain the view if you have the time and patience, Gentoo with KDE is better) and a powerful system management application called YaST which makes administering your system easy (or at least in some instances that is the idea).

Since the release of KDE 4.6 things have been looking very good for KDE and given openSUSE is a strong KDE distribution with many KDE developers behind it, if you are looking for a solid and usable desktop environment KDE 4.6.x (in other words openSUSE 11.4) is a great choice.

The openSUSE project could do with more users, so if you are looking to try something different openSUSE is definitely worth considering.


Its funny how things can change in just a few months,  not so long ago I would have been quite happy to recommend Ubuntu or Fedora but with current developments this is no longer the case.

And not so long ago I was voicing my annoyance with openSUSE 11.4 but believe me, its nothing compared to Unity and Gnome 3.
Read More..