并发编程基础知识
1、JVM使用的线程模型是哪一种?
线程模型包括ULT(用户线程)和KLT(内核线程),JVM规范中没有规定必须使用哪种线程模型,但目前主流的虚拟机使用的都是KLT。
2、Java多线程实现方式
2.1 继承Thread类
继承Thread类,并在子类中重写Thread类的run()方法,然后通过new继承类的实例,实现多线程。缺点是Java只能单继承,无法继承其他类。
public class MyThread extends Thread {
@Override
public void run() {
System.out.println(currentThread().getName() + " started.");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(currentThread().getName() + " end.");
}
public static void main(String[] args) {
for (int i = 0; i < 100; i++) {
MyThread myThread = new MyThread();
myThread.start();
}
}
}
2.2 实现Runnable接口
与继承Thread类相比,是更常用的实现多线程的方法。实现Runnable接口,需要重写run()方法。然后通过new实现类的实例,实现多线程。
public class MyThreadImplRunable implements Runnable {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "started");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "end");
}
public static void main(String[] args) {
for (int i = 0; i < 100; i++) {
new MyThreadImplRunable().run();
}
}
}
2.3 实现Callable接口
与线程池配合使用,实现类需要实现Callble接口,重写call()方法,注意call方法是有返回值的。这里通过调用future.get()方法获取返回值,该方法会阻塞直到线程执行结束,并返回结果。
import java.util.concurrent.*;
public class MyThreadWithCallable implements Callable {
@Override
public Object call() throws Exception {
System.out.println(Thread.currentThread().getName() + " started");
int sum = 0;
for (int i = 0; i < 100; i++) {
sum += i;
}
System.out.println(Thread.currentThread().getName() + " end");
return sum;
}
public static void main(String[] args) throws ExecutionException, InterruptedException {
ExecutorService executorService = Executors.newFixedThreadPool(10);
for (int i = 0; i < 100; i++) {
Future<?> future = executorService.submit(new MyThreadWithCallable());
Integer count = (Integer) future.get();
System.out.println(count);
}
}
}
2.4 使用Java线程池(单独讲解)
3、Java线程池的使用


