Java基础之线程实现的三种方式
一、实现的三种方式
Java 不支持多重继承,因此继承了 Thread 类就无法继承其它类,但是可以实现多个接口;
类可能只要求可执行就行,继承整个 Thread 类开销过大。
1、实现Runnable接口类
public class OneThread implements Runnable{
@Override
public void run() {
System.out.println("卢本伟");
}
}
2、实现Callable接口类
public class TwoThread implements Callable<String> {
@Override
public String call() throws Exception {
return "卢本伟";
}
}
3、继承Thread类
public class ThreeThread extends Thread {
@Override
public void run() {
System.out.println("卢本伟");
}
}
4、调用
@Test
void test1() throws ExecutionException, InterruptedException {
OneThread oneThread = new OneThread();
Thread thread1= new Thread(oneThread);
thread1.start();
TwoThread twoThread = new TwoThread();
FutureTask<String> stringFutureTask = new FutureTask<>(twoThread);
Thread thread2 = new Thread(stringFutureTask);
thread2.start();
System.out.println(stringFutureTask.get());
ThreeThread threeThread = new ThreeThread();
threeThread.start();
}
二、线程机制
Executor 管理多个异步任务的执行,而无需程序员显式地管理线程的生命周期。这里的异步是指多个任务的执行互不干扰,不需要进行同步操作。主要有三种 Executor。
- CachedThreadPool: 一个任务创建一个线程;
- FixedThreadPool: 所有任务只能使用固定大小的线程;
- SingleThreadExecutor: 相当于大小为 1 的 FixedThreadPool。
public static void main(String[] args) {
ExecutorService executorService = Executors.newCachedThreadPool();
for (int i = 0; i < 5; i++) {
executorService.execute(new MyRunnable());
}
executorService.shutdown();
}
三、线程同步synchronized
1、同步一个代码块
public void func() {
synchronized (this) {
// ...
}
}
它只作用于同一个对象,如果调用两个对象上的同步代码块,就不会进行同步。对于以下代码,使用 ExecutorService
执行了两个线程,由于调用的是同一个对象的同步代码块,因此这两个线程会进行同步,当一个线程进入同步语句块时,另一个线程就必须等待。
public class SynchronizedExample {
public void func1() {
synchronized (this) {
for (int i = 0; i < 10; i++) {
System.out.print(i + " ");
}
}
}
}
public static void main(String[] args) {
SynchronizedExample e1 = new SynchronizedExample();
ExecutorService executorService = Executors.newCachedThreadPool();
executorService.execute(() -> e1.func1());
executorService.execute(() -> e1.func1());
}
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9
2、同步一个方法
public synchronized void func () {
// ...
}
它和同步代码块一样,作用于同一个对象。
3、同步一个类
public void func() {
synchronized (SynchronizedExample.class) {
// ...
}
}
作用于整个类,也就是说两个线程调用同一个类的不同对象上的这种同步语句,也会进行同步。
public class SynchronizedExample {
public void func2() {
synchronized (SynchronizedExample.class) {
for (int i = 0; i < 10; i++) {
System.out.print(i + " ");
}
}
}
}
public static void main(String[] args) {
SynchronizedExample e1 = new SynchronizedExample();
SynchronizedExample e2 = new SynchronizedExample();
ExecutorService executorService = Executors.newCachedThreadPool();
executorService.execute(() -> e1.func2());
executorService.execute(() -> e2.func2());
}
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9
4、同步一个静态方法
public synchronized static void fun() {
// ...
}
作用于整个类。
- 你多学一样本事,就少说一句求人的话。
- 愿你如月光,明亮不清冷。
- 生活本来就是一场恶战,给止疼药也好,给巴掌也罢,最终都是要单枪匹马练就自身胆量,谁也不例外。
- 只有足够强大才有权利选择你想要的。
- 你是我秋日踩在金黄落叶上的浪漫。
- 人各有志,自己的路自己走。
- 山抹微云,天粘衰草,画声断谯门
- 不要着急,最好的总会在最不经意的时候出现。让我们怀揣希望去努力,静待美好的出现。
- 因为无能为力,所以顺其自然。因为心无所恃,所以随遇而安。任何一件事情,只要心甘情愿,总是能够变得简单,不为则难,为之则易。
- 梦想尚未实现,还有高峰不曾抵达,未来,让我们更有力量!