多线程有几种实现方法?分别是什么?
1.继承Thread类,重写run()方法,代码如下
步骤:
(1)继承Tread类,重写run()方法(线程要实现的东西)
(2) new一个子类实例
(3) 执行start方法
public class ExtendThreadTest extends Thread {
@Override
public void run(){
System.out.println("线程任务进行。。。");
}
public static void main(String[] args){
System.out.println("new 实例。。。");
ExtendThreadTest threadTest = new ExtendThreadTest();
System.out.println("启动线程");
threadTest.start();
}
}
2.实现Runable接口,重写run()方法,把此类作为target传入创建的Thread类中(这种方法的好处,就是java不支持多继承,但是支持多实现,当一个类已经继承其他类的时候,可以用这个方法),代码如下:
步骤:
(1)实现Runnable方法,重写run()(线程中要实现的东西)
(2)new Thread实例,传对象(new 实现类)进去
(3)执行start方法
public class ImplRunnableTest implements Runnable {
@Override
public void run() {
System.out.println("线程处理。。。");
}
public static void main(String[] args){
System.out.println("new 实例,传参");
ImplRunnableTest runnableTest = new ImplRunnableTest();
Thread thread = new Thread(runnableTest);
System.out.println("执行start方法");
thread.start();
}
}
3.实现Callable,重写call()方法,然后用FutureTask包装,作为target传入Thread实例中,这样可以处理线程中需要返回的数,用FutureTask中get()获取返回值,代码如下:
步骤:
1.实现Callable类,重写call()方法
2.new实现类的实例
3.用FutureTask类包装实现类
4.将FutureTask 对象作为target 传给Tread
5.调用start()启动线程
其中,可以改用FutureTask类中get()方法获取call方法中的返回值
public class ImplCallableTest2 implements Callable<Integer> {
@Override
public Integer call() throws Exception {
Integer i = 1;
return i;
}
public static void main(String[] args){
System.out.println("new Callable实现类实例");
ImplCallableTest2 callableTest2 = new ImplCallableTest2();
System.out.println("用FutureTask类包装实现类");
FutureTask<Integer> futureTask = new FutureTask<>(callableTest2);
System.out.println("把futureTask对象作为target传入Tread");
Thread thread = new Thread(futureTask);
System.out.println("启动线程");
thread.start();
System.out.println("用get()方法获取返回值");
try {
System.out.println(futureTask.get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}
4.利用线程池创建
(Executors类:提供了一系列工厂方法用于创建线程池,返回的线程池都实现了ExecutorService接口。
但是不推荐使用这种方法,而是通过ThreadPoolExecutor的方式,自己设置一些参数,明确运行规则
,避免一些其他问题导致OOM,阿里建议多线程采用线程池的方法,减少线程上下文切换所带来的的损耗,并且帮忙管理线程,避免不必要的问题)
public class TreadFactoryTest {
public static void main(String[] args){
//核心线程数
int corePoolSize = 2;
//最大线程数
int maximumPoolSize = 4;
//最大空闲时间
long keepAliveTime = 10;
//最大空闲时间单位
TimeUnit timeUnit = TimeUnit.SECONDS;
//阻塞队列
BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<>(2);
//线程工厂
ThreadFactory threadFactory = new NameTreadFactory();
//拒绝策略
RejectedExecutionHandler handler = new RejectPolicy();
ThreadPoolExecutor executor = null;
try {
//推荐使用这种方式创建线程池
executor = new ThreadPoolExecutor(corePoolSize,maximumPoolSize,keepAliveTime,timeUnit,
workQueue,threadFactory,handler);
//预启动所有核心线程,提升效率
executor.prestartAllCoreThreads();
//任务数
int count = 10;
for (int i = 1; i <=count; i++) {
RunnableTask task = new RunnableTask(String.valueOf(i));
executor.submit(task);
}
} finally {
assert executor != null;
executor.shutdown();
}
}
static class NameTreadFactory implements ThreadFactory {
//线程Id
private final AtomicInteger threadId = new AtomicInteger(1);
@Override
public Thread newThread(Runnable r) {
Thread thread = new Thread(r,"线程-"+threadId.getAndIncrement());
System.out.println(thread.getName()+"已经被创建");
return thread;
}
}
public static class RejectPolicy implements RejectedExecutionHandler {
@Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
doLog(r,executor);
}
private void doLog(Runnable r, ThreadPoolExecutor executor){
System.err.println(r.toString()+" rejected");
}
}
static class RunnableTask implements Runnable{
private String name;
public RunnableTask(String name){
this.name=name;
}
@Override
public void run() {
System.out.println(this.toString()+" is running!");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@Override
public String toString() {
return "RunnableTask{" +
"name='" + name + '\'' +
'}';
}
}
}
点击查看更多内容
为 TA 点赞
评论
共同学习,写下你的评论
评论加载中...
作者其他优质文章
正在加载中
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦