In general I think the STM solution to most concurrency issues looks
promising, however in the case of dining philosophers I found that Java
locking was easier than a ref, atom or agent solution.

;;
(import java.util.concurrent.locks.ReentrantReadWriteLock)

(defn nth-chopstick [chopsticks i side]
  (if (= side :right)
    (nth chopsticks (- i 1) (nth chopsticks 4))
    (nth chopsticks i)))

(defn delay-rand [max]
  (Thread/sleep (rand max)))

(defmacro with-lock [lock & body]
  `(do
    (.lock ~lock)
    ~...@body
    (.unlock ~lock)))

(defn dine [grab-delay]
  (let [chopsticks (for [i (range 5)] (.writeLock (
ReentrantReadWriteLock.)))
        print-lock (.writeLock (ReentrantReadWriteLock.))
        serial-print (fn [str] (with-lock print-lock (println str)))]
    (dotimes [i 5]
      (.start
       (Thread.
        (fn []
          (loop []
            (delay-rand grab-delay)
            (serial-print (str "Philosopher " (inc i) " picking up
chopsticks"))
            (with-lock (nth-chopstick chopsticks i :left)
                       (delay-rand grab-delay)
                       (with-lock (nth-chopstick chopsticks i :right)
                                  (serial-print (str "Philosopher " (inc i)
" eating"))
                                  (delay-rand grab-delay)))
            (serial-print (str "Philosopher " (inc i) " thinking"))
            (delay-rand (* grab-delay 4))
            (recur))))))))


On Thu, Sep 17, 2009 at 7:12 PM, Rick Moynihan <rick.moyni...@gmail.com>wrote:

>
> 2009/9/17 Hugh Aguilar <hugoagui...@rosycrew.com>:
> >
> > Thanks for the encouragement. I've already got the book.
> >
> > I suppose eventually I will have to learn Java. I have been putting it
> > off because I hear a lot of Java-bashing from programmers, and have
> > also noted that this is generally the impetus for the development of
> > languages such as Clojure and Scala and the dozens of others. On the
> > other hand, Java can't be any more difficult than C or C++ that I
> > already know. With languages such as Factor or Python I am relying on
> > the bindings to C and C++ programs, so with Clojure I would be relying
> > on the bindings to Java programs, which might be an improvement.
>
> I'm pretty sure that given you're already familiar with class based OO
> languages in the form of C++ and Python that Java won't prove a
> significant barrier to your learning clojure.
>
> The main thing you'll use java for in Clojure is accessing API's, and
> if you can read javadocs and know what classes, objects, methods and
> constructors are then you'll already know at least 80% of what you
> need to be able to usefully make use of Java via Clojure.
>
> Some things you'll probably need to know are:
>
> - Class files are typically held in jar files (which are essentially
> just zip files with a different extension.
> - Jars are typically put onto the classpath as commandline arguments
> when starting the JVM with the java command e.g.
>
>  $ java -cp /path/to/first.jar:/path/to/second.jar myfile.clj
>
> - Java Classes are namespaced into packages e.g. the java.util.HashMap
> etc...  java.util is the package, HashMap is the class...  HashMap can
> be referenced unambiguously by the fullyqualified name
> java.util.HashMap.
> - How classes/packages map into clojure namespaces etc...
>
> - What Java interfaces are and how they work
> - How to use "proxy" to implement interfaces in Clojure (proxy is
> typically how we simulate java anonymous classes in Clojure).
> - How to call methods on java objects with . .. and doto
> - How to use class (static) methods.
>
> There are lots of things that complicate this picture but to get
> started I'm guessing most questions other than those above will be
> relatively easily resolved.
>
> To get a feel for java interop, I'd suggest trying to use the java
> standard library first as that way you wont need to mess about with
> downloading jars and altering the classpath... e.g. paste the
> following into a REPL:
>
> (let [java-hash-map (new java.util.HashMap)]
>  (doto java-hash-map
>    (. put "key" "value")
>    (. put "key2" "value2")
>    (. put "key3" "value3"))
>  (prn (str java-hash-map)))
>
> From here and playing with Files etc... use proxy to implement a java
> Interface which you feed to another java class, then when you get the
> hang of this, you'll probably want to start using other libraries.  If
> you've done this I'd say you'll have mastered most of java/clojure
> interop and will know enough to use Java API's 90% of the time without
> problem.
>
> R.
>
> >
>

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to