目录
进程与线程
什么是进程?
进程是正在运行的程序的实例,进程是线程的容器,即一个进程中可以开启多个线程。
什么是线程?
线程是进程内部的一个独立执行单元,一个进程可以同时并发运行多个线程。
创建线程的方式
Java中创建线程的4种方式
- 继承Thread类
- 实现Runnable接口
- 实现Callable接口
- 线程池
1.继承Thread类
public class MyThread extends Thread {
@Override
public void run(){
for (int i = 0; i < 10; i++) {
System.out.println("MyThread执行了"+ System.currentTimeMillis());
}
}
}
2.实现Runnable接口
public class MyRunnable implements Runnable {
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName()+"执行时间:"+System.currentTimeMillis()+"执行次数"+i);
}
}
}
3.实现Callable接口
public class MyCallable implements Callable<String> {
public String call() throws Exception {
for (int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName()+"执行时间:"+System.currentTimeMillis()+"执行次数"+i);
}
return "MyCallable";
}
}
4.线程池
具体可以参考 :https://blog.csdn.net/qq_36110736/article/details/108612376
ThreadPoolExecutor executor =new ThreadPoolExecutor(1, 2, 1000, TimeUnit.MILLISECONDS, new SynchronousQueue<Runnable>(),Executors.defaultThreadFactory(),new ThreadPoolExecutor.AbortPolicy());
executor.execute(new MyRunnable());
补充
在Java中,每次程序运行至少启动2个线程,一个是main线程,一个是垃圾收集线程。
实现接口和继承Thread类比较
- 接口更适合多个相同的线程去共享一个资源。
- 接口可以避免Java中单继承的局限性
- 接口代码可以被多个线程共享,代码和线程独立。
- 线程池只能放入实现Runnable或Callable接口的线程,不能直接放入继承Thread的类。
Runnable接口和Callable接口的比较
相同点
- 都是接口
- 两者都可以用来编写多线程程序
- 都需要调用Thread.star()启动线程
不同点
- 实现Callable接口的线程能返回执行结果,而实现Runnable接口的线程不能返回结果
- Callable节后的call()方法允许抛出异常,而Runnable接口的run方法不允许抛出异常
- 实现Callable接口的线程可以调用Future.cancel取消执行,而实现Runnable接口的线程则不能。
注意:
Callable接口支持返回执行结果,此时需要调用FutureTask.get()方法实现,此时会阻塞主线程,直到获取“将来”结果,当不调用此方法时,主线程不会阻塞。
测试类
package thread;
import java.util.concurrent.*;
public class CreateThreadTest {
public static void main(String[] args) {
// MyThread myThread = new MyThread();
// myThread.start();
// Thread thread = new Thread(new MyRunnable(),"MyRunnable");
// thread.start();
// FutureTask<String> futureTask = new FutureTask<String>(new MyCallable());
// Thread thread = new Thread(futureTask,"MyCallable");
// thread.start();
// try {
// String result = futureTask.get();
// System.out.println(result);
// } catch (InterruptedException e) {
// e.printStackTrace();
// } catch (ExecutionException e) {
// e.printStackTrace();
// }
// for (int i = 0; i < 10; i++) {
// System.out.println("Main执行了"+System.currentTimeMillis());
// }
ThreadPoolExecutor executor =new ThreadPoolExecutor(1, 2, 1000, TimeUnit.MILLISECONDS, new SynchronousQueue<Runnable>(),Executors.defaultThreadFactory(),new ThreadPoolExecutor.AbortPolicy());
executor.execute(new MyRunnable());
Future<String>future =new Future(new MyCallable())
}
}