In the context of the problem, non-blocking means no deadlock. I.e., a philosopher will not suspend indefinitely waiting for one fork while already holding the other fork. Suspension means that the thread is disabled for scheduling purposes and will not execute until another thread specifically resumes the suspended thread. The solution must avoid indefinite suspension or deadlock (i.e., 2 or more threads suspended waiting on each other to proceed).
The solution requires an arbitrator that can atomically grant both forks or reject the request. If the philosopher cannot atomically take both forks, then the philosopher must think about life, the universe and everything else for a random amount of time. After thinking, the philosopher again requests to the arbitrator to acquire atomically both forks. Eating also delays for a random time before relinquishing both forks. All random delays are finite with a common upper limit, say, 10 seconds or 10 minutes, whatever.
This design requires a compare-and-swap mechanism to examine and conditionally update a bit mask, with one bit for each fork. The mechanism is atomic. Either both bits are updated or neither are updated.
A sample solution in java for an arbitrary number of philosophers that uses only volatile fields and no synchronized() blocks or suspension locks is available at:
sourceforge.net/projects/javamutex/