Java 多线程,Java创建线程4种方式,Java 四种方式创建线程
实现Runnable 接口和继承 Thread类的区别
================================
©Copyright 蕃薯耀 2021-04-16
https://blog.csdn.net/w995223851
一、Java创建线程的四种方式
1、继承 Thread类
public class Threadable extends Thread{
@Override
public void run() {
System.out.println("Threadable 当前线程是:" + Thread.currentThread().getName());
}
}
2、实现 Runnable 接口
public class ThreadRun implements Runnable{
@Override
public void run() {
System.out.println("ThreadRun 当前线程是:" + Thread.currentThread().getName());
}
}
实现Runnable 接口和继承 Thread类的区别:
- synchronized(this)中使用this时,this是当前对象,继承 Thread类的方式创建多个线程时,this是不一样的,会出问题。实现Runnable 接口因为只有一个,所以没问题。
- synchronized(obj):可以在线程类创建一个obj对象,表示线程共用对象,这样给加锁的对象是同一个。需要注意的是:实现Runnable接口创建的对象不用加static,继承 Thread类创建的对象必须加static,不然对象就不是同一个。
- synchronized(XXX.class):使用类,类只有一个,能解决synchronized(obj)的问题(继承 Thread类创建的对象必须加static)。在Java中,任何东西都被看作对象,所以类也是可以的。
所以一般情况,建设使用实现Runnable 接口的方式,避免继承Thread存在的问题。
3、实现 Callable<V> 接口
import java.util.concurrent.Callable;
public class ThreadCallable implements Callable<Object> {
@Override
public Object call() throws Exception {
return null;
}
}
和实现 Runnable 接口的区别是:
- Callable可以往外抛异常
- Callable有返回值
4、使用线程池创建
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ThreadTest5Executors {
public static void main(String[] args) {
ThreadRunData threadRun = new ThreadRunData();
//创建线程池,池里有10个线程
ExecutorService executorService = Executors.newFixedThreadPool(10);
executorService.execute(threadRun);//execute是没返回的
executorService.execute(threadRun);//execute是没返回的
executorService.submit(threadRun);//submit是有返回的
executorService.submit(threadRun);//submit是有返回的
//executorService.submit(task);//submit是有返回的,如果使用Callable且有返回值,则需要使用submit
//关闭线程池
executorService.shutdown();
}
}
二、Java 多线程 Synchronized 关键字使用
synchronized(object对象)
- synchronized(this):this表示调用的当前对象
- synchronized(obj):可以在线程类创建一个obj对象,表示线程共用对象,这样给加锁的对象是同一个。需