一、继承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. 删除一个数字之后数列gcd最大

    ★实验任务 顾名思义,互质序列是满足序列元素的 gcd 为 1 的序列.比如[1,2,3], [4,7,8],都是互质序列.[3,6,9]不是互质序列.现在并不要求你找出一个互质 序列,那样太简单了! ...

  2. 三公网络监督平台APP上线,源代码出售。

  3. Linux操作系统(三)

    文件系统: boot sector:记录引导文件 sb: super block 每个文件系统只有一个sb,其余black group均是它的备份 读写文件会进入到inode operation vf ...

  4. 第一个spring冲刺心得及感想

    在这次spring中,学到了不少东西: 1.团队协作精神 2.任务细节化,任务燃尽图 3.身为sm的责任 但是在过程中也认识到了一些不足 1.对于团队协作完成一个大的项目还是不熟悉 2.个人能力的不足 ...

  5. Linux_Nginx 安装

    官网:http://nginx.org/ 1.下载http://nginx.org/download/nginx-1.14.0.tar.gz 2.查看详情 [zwesy@localhost ~]$ l ...

  6. java使用Cookie判断用户登录情况

    1.判断是否登录 public boolean isLogin() { Set<Cookie> cookies = this.browser.getCookies(); String JS ...

  7. DAY4-Python学习笔记

    1.XML: 操作XML有两种方法:DOM和SAX DOM:把整个XML读入内存,解析为树,因此占用内存大,解析慢,优点是可以任意遍历树的节点 SAX:是流模式,边读边解析,占用内存小,解析快,缺点是 ...

  8. Just Another Problem UVA - 11490(枚举)

    题意: 你有s个士兵,并打算把他们排成一个r行c列,但有两个"洞"的矩形方队,以迷惑敌人(从远处看,敌人可能误以为一共有r*c个士兵).洞是两个大小相同的正方形,为了隐蔽性更强,方 ...

  9. Be the Winner HDU - 2509(反博弈。。这样叫应该没错吧。。)

    就是   好几堆苹果  每堆苹果排成一条线  可以任意从每堆拿苹果   如果一堆苹果里拿了之后  则有两种情况 1.从不是边缘拿   拿完这一堆变成两堆 2.从边缘拿   拿完还是一堆 题目还要求 谁 ...

  10. IoT与区块链的机遇与挑战

    区块链, 分布式账本技术的一种形式, 自从2014年或多或少地获得了大量的关注: 区块链和物联网, 区块链和安全, 区块链和金融, 区块链和物流, 凡是你能想到的,仿佛都可以应用区块链. 在本文中, ...