语言和并发-01启动线程
概述
本系列文章意在比较Java与Clojure在线程实现上的区别!
Java的线程主要基于锁机制,而Clojure主要模拟了数据库事务操作,所谓的STM(软事务模型)。主要从代码层面给出两者的区别,孰优孰劣请自行判断!
启动线程
Java代码
- Java实例中,两个线程类A和B,分别通过实现Runnable接口和继承Thread类来实现
- 两各类启动线程的方式有差异,详见代码
- JDK5中提供了线程启动类Executors来执行
package concurrent;
import java.util.concurrent.*;
/**
* Created by ivan on 15-2-22.
* Java启动线程
*/
public class Start {
public static void main(String[] args) throws InterruptedException, ExecutionException {
//实现Runnable接口,需要通过一个Thread实例来启动线程
new Thread(new A()).start();
//继承Thread类,直接通过自身来启动线程
new B().start();
//JDK1.5开始,可以通过Executor来执行线程.效果和上面没有区别
ExecutorService e = Executors.newCachedThreadPool();
e.execute(new A());
e.execute(new B());
//Callable需要submit,返回Future
Future<String> f = e.submit(new C());
//get方法是个阻塞方法
System.out.println("Future f = " + f.get());
e.shutdown();
}
}
/**
* 线程类可以实现Runnable接口
*/
class A implements Runnable {
@Override
public void run() {
for (int i = 0; i < 9; i++) {
System.out.println("ThreadID:" + Thread.currentThread().getId() + " | i = " + i);
try {
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
/**
* 线程类也可以继承Thread类
*/
class B extends Thread {
@Override
public void run() {
for (int i = 0; i < 9; i++) {
System.out.println("ThreadID:" + Thread.currentThread().getId() + " | i = " + i);
try {
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
/**
* 如果想线程返回结果,则实现Callable接口
*/
class C implements Callable<String> {
@Override
public String call() throws Exception {
for (int i = 0; i < 9; i++) {
System.out.println("ThreadID:" + Thread.currentThread().getId() + " | i = " + i);
try {
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return "End";
}
}
Clojure代码
- Clojure可以直接对函数进行多线程执行,因为它没有类的概念
- Clojure可以直接通过Java的Thread类来启动多线程
- 也可以通过future来执行多线程
- future可以返回值,可对其进行解引用,获得返回值,如果线程未执行完,则阻塞。
- future实际上就是Java中Future实例,可以直接调用future的get方法获取返回值,效果和解引用相同
(ns concurrent.start)
;Clojure没有类的概念,直接给出函数
(defn f []
(dotimes [i 9]
(println " | i = " i)
(Thread/sleep 300))
:End)
;可以通过Java的Thread来执行
(.start (Thread. f))
;Clojure提供了future宏,可以方便的在另一个线程内执行
(def fu (future (f)))
;主线程结束
(println "End")
;对future可以解引用,获取计算结果,如果解引用时,future没执行完,会阻塞
(println "fu result = " @fu)
;fu实际上就是Java中的Future,所以可以使用Future的get方法,效果和解引用相同
(println "Future.get = " (.get fu))
;调用此方法结束所有线程
(shutdown-agents)