一、继承Thread类

public class Demo1 extends Thread {

    public Demo1(String name) {
super(name);
} @Override
public void run() {
while(!interrupted()) {
System.out.println(getName() + "线程执行了 .. ");
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} public static void main(String[] args) { Demo1 d1 = new Demo1("first-thread");
Demo1 d2 = new Demo1("second-thread"); d1.start();
d2.start(); // d1.stop();
d1.interrupt();
} }

二、实现Runnable 接口

/**
* 作为线程任务存在
*
* @author worker
*
*/
public class Demo2 implements Runnable { @Override
public void run() {
while(true) {
System.out.println("thread running ...");
}
} public static void main(String[] args) {
Thread thread = new Thread(new Demo2());
thread.start();
} }

三、匿名内部类的方式

public class Demo3 {

    public static void main(String[] args) {

        /*new Thread() {
public void run() {
System.out.println("thread start ..");
};
}.start();*/ /*new Thread(new Runnable() {
@Override
public void run() {
System.out.println("thread start ..");
}
}).start();*/ new Thread(new Runnable() {
@Override
public void run() {
System.out.println("runnable");
}
}) {
public void run() {
System.out.println("sub");
};
}.start(); } }

四、带返回值的线程

import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask; public class Demo4 implements Callable<Integer> { public static void main(String[] args) throws Exception {
Demo4 d = new Demo4(); FutureTask<Integer> task = new FutureTask<>(d); Thread t = new Thread(task); t.start(); System.out.println("我先干点别的。。。"); Integer result = task.get();
System.out.println("线程执行的结果为:" + result);
} @Override
public Integer call() throws Exception {
System.out.println("正在进行紧张的计算....");
Thread.sleep(3000);
return 1;
} }

五、定时器

import java.util.Timer;
import java.util.TimerTask; public class Demo5 { public static void main(String[] args) { Timer timer = new Timer(); timer.schedule(new TimerTask() { @Override
public void run() {
// 实现定时任务
System.out.println("timertask is run");
}
}, 0, 1000); } }

六、线程池的实现

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; public class Demo6 { public static void main(String[] args) { ExecutorService threadPool = Executors.newCachedThreadPool(); for (int i = 0; i < 1000; i++) {
threadPool.execute(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName());
}
});
} threadPool.shutdown();
} }

七、Lambda表达式实现

import java.util.Arrays;
import java.util.List; public class Demo7 { public static void main(String[] args) { List<Integer> values = Arrays.asList(10,20,30,40);
int res = new Demo7().add(values);
System.out.println("计算的结果为:" + res); } public int add (List<Integer> values) {
// values.parallelStream().forEach(System.out :: println);
return values.parallelStream().mapToInt( i -> i * 2).sum();
} }

八、Spring实现多线程

spring通过任务执行器TaskExecutor来实现多线程与并发编程。通常使用ThreadPoolTaskExecutor来实现一个基于线程池的TaskExecutor.

首先你要实现AsyncConfigurer 这个接口,目的是开启一个线程池.

import java.util.concurrent.Executor;

import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; /**
* 注入一个线程池
* @author mingge
*
*/ @Configuration
@ComponentScan("com.foreveross.service.weixin.test.thread")
@EnableAsync
public class TaskExecutorConfig implements AsyncConfigurer { @Override
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor taskExecutor=new ThreadPoolTaskExecutor();
taskExecutor.setCorePoolSize(5);
taskExecutor.setMaxPoolSize(20);
taskExecutor.setQueueCapacity(25);
taskExecutor.initialize();
return taskExecutor;
} @Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return null;
} }

然后注入一个类,实现你的业务,并在你的Bean的方法中使用@Async注解来声明其是一个异步任务

import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service; /**
* 线程池任务
* @author mingge
*
*/
@Service
public class TaskService { @Async
public void executeAsyncTask(int i){
System.out.println("执行异步任务:"+i);
} @Async
public void executeAsyncTask1(int i){
System.out.println("执行异步任务1:"+(i+i));
}
}

最后通过测试,可以看到你的实现是异步执行了.

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

/**
*
* @author mingge
*
*/
public class Test { public static void main(String[] args) {
AnnotationConfigApplicationContext context=new AnnotationConfigApplicationContext(TaskExecutorConfig.class);
TaskService taskService=context.getBean(TaskService.class);
for(int i=0;i<20;i++){
taskService.executeAsyncTask(i);
taskService.executeAsyncTask1(i);
}
//最后可以根据结果可以看出结果是并发执行而不是顺序执行的呢
context.close();
}
}

方式二:XML方式

spring就提供了ThreadPoolTaskExecutor这个类来实现线程池,线程池是啥,可以理解为数据源,或者有一堆线程的池子也行

在spring配置中我们可以写好如下代码(大致意思都在注释中,不多说了,百度也一堆):

<bean id="taskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
<!-- 核心线程数 -->
<property name="corePoolSize" value="5" />
<!-- 最大线程数 -->
<property name="maxPoolSize" value="10" />
<!-- 队列最大长度 >=mainExecutor.maxSize -->
<property name="queueCapacity" value="25" />
<!-- 线程池维护线程所允许的空闲时间 -->
<property name="keepAliveSeconds" value="3000" />
<!-- 线程池对拒绝任务(无线程可用)的处理策略 ThreadPoolExecutor.CallerRunsPolicy策略 ,调用者的线程会执行该任务,如果执行器已关闭,则丢弃. -->
<property name="rejectedExecutionHandler">
<bean class="java.util.concurrent.ThreadPoolExecutor$CallerRunsPolicy" />
</property>
</bean>

然后定义一个component组件,然后线程的引用就十分简单了,只要把这个线程扔进这个线程池子就行了

@Component
public class FileCutter { @Autowired
private TaskExecutor taskExecutor; public void filesMng(String path, String fileName) {
this.taskExecutor.execute(new CutFilesThread(path,fileName));
} private class CutFilesThread implements Runnable {
private String path;
private String fileName;
private CutFilesThread(String path, String fileName) {
super();
this.path = path;
this.fileName = fileName;
}
@Override
public void run() {
System.out.println("barry... run...");
// display(path, fileName);
}
}

最后在你所需要的地方就可以调用这个组件了,不论是service还是controller都行

@Autowired
private FileCutter fileCutter; @RequestMapping("/cut")
@ResponseBody
public Object cut(){
fileCutter.filesMng("your path", "your fileName");
return "success";
}

另外可以参考:https://blog.csdn.net/king_kgh/article/details/76022136

参考资料:

龙果学院《Java并发编程原理与实战》

Java并发编程原理与实战五:创建线程的多种方式的更多相关文章

  1. Java并发编程原理与实战七:线程带来的风险

    在并发中有两种方式,一是多进程,二是多线程,但是线程相比进程花销更小且能共享资源.但使用多线程同时会带来相应的风险,本文将展开讨论. 一.引言 多线程将会带来几个问题: 1.安全性问题 线程安全性可能 ...

  2. Java并发编程原理与实战四:线程如何中断

    如果你使用过杀毒软件,可能会发现全盘杀毒太耗时间了,这时你如果点击取消杀毒按钮,那么此时你正在中断一个运行的线程. java为我们提供了一种调用interrupt()方法来请求终止线程的方法,下面我们 ...

  3. Java并发编程原理与实战二十五:ThreadLocal线程局部变量的使用和原理

    1.什么是ThreadLocal ThreadLocal顾名思义是线程局部变量.这种变量和普通的变量不同,这种变量在每个线程中通过get和set方法访问, 每个线程有自己独立的变量副本.线程局部变量不 ...

  4. Java并发编程原理与实战十五:手动实现一个可重入锁

     package com.roocon.thread.ta1; public class Sequence { private MyLock lock = new MyLock(); private ...

  5. Java并发编程原理与实战三十一:Future&FutureTask 浅析

    一.Futrue模式有什么用?------>正所谓技术来源与生活,这里举个栗子.在家里,我们都有煮菜的经验.(如果没有的话,你们还怎样来泡女朋友呢?你懂得).现在女票要你煮四菜一汤,这汤是鸡汤, ...

  6. Java并发编程原理与实战十:单例问题与线程安全性深入解析

    单例模式我想这个设计模式大家都很熟悉,如果不熟悉的可以看我写的设计模式系列然后再来看本文.单例模式通常可以分为:饿汉式和懒汉式,那么分别和线程安全是否有关呢? 一.饿汉式 先看代码: package ...

  7. Java并发编程原理与实战九:synchronized的原理与使用

    一.理论层面 内置锁与互斥锁 修饰普通方法.修饰静态方法.修饰代码块 package com.roocon.thread.t3; public class Sequence { private sta ...

  8. Java并发编程原理与实战八:产生线程安全性问题原因(javap字节码分析)

    前面我们说到多线程带来的风险,其中一个很重要的就是安全性,因为其重要性因此,放到本章来进行讲解,那么线程安全性问题产生的原因,我们这节将从底层字节码来进行分析. 一.问题引出 先看一段代码 packa ...

  9. Java并发编程原理与实战四十二:锁与volatile的内存语义

    锁与volatile的内存语义 1.锁的内存语义 2.volatile内存语义 3.synchronized内存语义 4.Lock与synchronized的区别 5.ReentrantLock源码实 ...

随机推荐

  1. url 地址含参数较多如何拼接

    url 地址拼接是经常会遇到的问题.所以必须要掌握这个技术 1.合并参数对象,循环出来. var commonParams = { g_tk: 1928093487, inCharset: 'utf- ...

  2. 10th 知识点学习:单元测试

    1.书中所在位置:构建之法第二章,19页—28页. 2.大致内容:书中是以案例的形式引入的介绍,具体讲述什么是单元测试,即程序员小飞进行练习单元测试,经过一系列的代码更改之后,终于成功实现.通过事后小 ...

  3. curl 实例详解

    使用PHP的cURL库可以简单和有效地去抓网页.你只需要运行一个脚本,然后分析一下你所抓取的网页,然后就可以以程序的方式得到你想要的数据 了.无论是你想从从一个链接上取部分数据,或是取一个XML文件并 ...

  4. [微软官网]SQLSERVER的版本信息

    来源:https://docs.microsoft.com/zh-cn/sql/sql-server/editions-and-components-of-sql-server-2017?view=s ...

  5. 微软自己的官网介绍 SSL 参数相关

    https://docs.microsoft.com/en-us/dotnet/api/system.security.authentication.sslprotocols?redirectedfr ...

  6. SpringBoot(五)_表单验证

    SpringBoot(五)_表单验证 参数校验在我们日常开发中非常常见,最基本的校验有判断属性是否为空.长度是否符合要求等,在传统的开发模式中需要写一堆的 if else 来处理这些逻辑,很繁琐,效率 ...

  7. LINQ 模糊搜索

    IList<entity> ls = new List<entity>(); ls = (from k in ls where k.Name.Contains("sa ...

  8. MT【159】单调有界有极限

    已知数列$\{a_n\}$满足:$a_n>0,a_{n+1}+\dfrac{1}{a_n}<2,n\in N^*$.求证:(1)$a_{n+2}<a_{n+1}<2 (n\in ...

  9. MT【146】一边柯西,一边舍弃

    (2018浙江省赛9题)设$x,y\in R$满足$x-6\sqrt{y}-4\sqrt{x-y}+12=0$,求$x$的范围______ 解答:$x+12=6\sqrt{y}+4\sqrt{x-y} ...

  10. [AT697]フィボナッチ

    题目大意:给你$n,k(n\leqslant10^9,k\leqslant10^3)$,求$f_n$.$f$数组满足$f_1=f_2=\cdots=f_k=1$,$f_n=\sum\limits_{i ...