事务、定时任务、多线程
1: 定时任务:
代码结构布局:
运行结果:
代码如下:
pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>Aop_0914_SecondStage</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<name>Aop_0914_SecondStage Maven Webapp</name>
<!-- FIXME change it to the project's website -->
<url>http://www.example.com</url>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<servlet.version>4.0.1</servlet.version>
<jsp.version>2.2</jsp.version>
<jstl.version>1.2</jstl.version>
<spring.version>5.3.14</spring.version>
<commons-dbcp.version>1.4</commons-dbcp.version>
<mybatis.version>3.4.6</mybatis.version>
<mybatis-spring.version>1.3.3</mybatis-spring.version>
<mysql-connector-java.version>8.0.11</mysql-connector-java.version>
<fastjson.version>1.2.78</fastjson.version>
</properties>
<dependencies>
<!-- 添加javaEE支持 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>${servlet.version}</version>
<!-- provided只在编译时支持,发布时不拷贝文件 -->
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>${jsp.version}</version>
<!-- provided只在编译时支持,发布时不拷贝文件 -->
<scope>provided</scope>
</dependency>
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>${jstl.version}</version>
</dependency>
<!-- 引入spring基础模块 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency>
<!--dbcp连接池 -->
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>${commons-dbcp.version}</version>
</dependency>
<!--mybatis-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>${mybatis.version}</version>
</dependency>
<!-- mybatis spring整合 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>${mybatis-spring.version}</version>
</dependency>
<!-- mybatis插件PageHelper -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.1.0</version>
</dependency>
<!--通用mapper插件-->
<dependency>
<groupId>com.github.abel533</groupId>
<artifactId>mapper</artifactId>
<version>3.0.1</version>
</dependency>
<!-- mysql驱动类 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql-connector-java.version}</version>
</dependency>
<!-- fastjson处理json数据 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>${fastjson.version}</version>
</dependency>
<!-- lombok 简化实体内容 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.24</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.11.2</version>
</dependency>
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>javax.mail</artifactId>
<version>1.5.6</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.30</version>
</dependency>
<dependency>
<groupId>com.github.xuwei-k</groupId>
<artifactId>html2image</artifactId>
<version>0.1.0</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.8</version>
</dependency>
<!-- <dependency>-->
<!-- <groupId>org.slf4j</groupId>-->
<!-- <artifactId>slf4j-simple</artifactId>-->
<!-- <version>1.7.25</version>-->
<!-- </dependency>-->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.13.2.2</version>
</dependency>
<!--logback记录文件日志-->
<dependency>
<groupId>org.logback-extensions</groupId>
<artifactId>logback-ext-spring</artifactId>
<version>0.1.4</version>
</dependency>
<!--数据校验-->
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>2.0.1.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.1.0.Final</version>
</dependency>
<!--文件生成-->
<!-- https://mvnrepository.com/artifact/org.apache.poi/poi -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.17</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.poi/poi-ooxml -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.17</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.poi/poi-ooxml-schemas -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml-schemas</artifactId>
<version>3.17</version>
</dependency>
<!--发送邮件-->
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>jakarta.mail</artifactId>
<version>1.6.7</version>
</dependency>
<!--定时任务所需要的包-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>5.3.1</version>
</dependency>
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.2.1</version>
</dependency>
</dependencies>
</project>
spring-task.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:task="http://www.springframework.org/schema/task"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd">
<!--扫描包-->
<context:component-scan base-package="com.util"/>
<!--用xml方式配置定时任务-->
<!-- <task:scheduled-tasks>-->
<!-- <task:scheduled ref="myTaskJob" method="task" cron="*/2 * * * * *"/>-->
<!-- </task:scheduled-tasks>-->
<!--注解方式实现定时任务-->
<!--开启注解配置-->
<context:annotation-config />
<!--开启这个配置,spring才能识别@Scheduled注解-->
<task:annotation-driven/>
</beans>
MyTaskJob:
package com.util;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
@Component("myTaskJob")
public class MyTaskJob {
//定义定时任务方法
public void task(){
System.out.println("这是一个定时任务,发短信,发邮件,数据库备份:"+ LocalDateTime.now());
}
//定义定时任务方法
@Scheduled(cron = "*/5 * * * * *")
public void task2(){
System.out.println("这是一个定时任务mytask2,发短信,发邮件,数据库备份:"+ LocalDateTime.now());
}
}
MyTest6 :
package com.test3;
import com.util.MyTaskJob;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MyTest6 {
public static void main(String[] args) {
//定时任务测试
ApplicationContext ac = new ClassPathXmlApplicationContext("spring-task.xml");
//MyTaskJob myTaskJob = ac.getBean(MyTaskJob.class);
}
}
2: 多线程 三种方式:
①代码结构布局:
运行结果:
代码如下:
MyThread :
package com.aaa.test;
/**
* 实现多线程编程的第一种方式:继承Thread类
* @author: hy
* @create: 2022-09-15 11:02:24
*/
public class MyThread extends Thread{
/**
* 多线程的任务处理方法
*/
@Override
public void run() {
//System.out.println("MyThread 执行了任务方法run");
for (int i=1;i<=10;i++){
//System.out.println("MyThread 执行了任务:"+i);
//Thread.currentThread().getName():通过线程类获取当前线程对象,获取线程名字
// 如果线程名字自己没有设置,则用序号表示线程
System.out.println(Thread.currentThread().getName()+" 执行了任务:"+i);
}
}
}
Test:
package com.aaa.test;
/**
* @author: hy
* @create: 2022-09-15 11:05:13
*/
public class Test {
public static void main(String[] args) {
//创建线程类
MyThread myThread = new MyThread();
//自己设置线程名字
//myThread.setName("Thread-aaa");
//直接调用线程的run方法,无法实现多线程的执行特征
//myThread.run();
//start:可以让线程处于就绪状态,能够被线程调度器进行调度管理,从而实现多线程的运行方式
myThread.start();
//start不能调用多次
//myThread.start();
//创建第二个线程对象
MyThread myThread2 = new MyThread();
myThread2.start();
//System.out.println("这是main方法的执行过程");
for (int i=1;i<=10;i++){
//System.out.println("Main方法执行:"+i);
System.out.println(Thread.currentThread().getName()+" 方法执行:"+i);
}
}
}
②代码结构布局:
运行结果:
代码如下:
MyRunnable :
package com.aaa.test2;
/**
* 实现多线程编程的第二种方式:定义类实现Runnable接口,用于定义线程要【执行的任务】
* @author: hy
* @create: 2022-09-15 11:37:28
*/
public class MyRunnable implements Runnable{
@Override
public void run() {
for (int i=1;i<=10;i++){
System.out.println(Thread.currentThread().getName()+"执行:"+i);
}
}
}
Test :
package com.aaa.test2;
/**
* @author: hy
* @create: 2022-09-15 11:39:53
*/
public class Test {
public static void main(String[] args) {
//创建多线程要执行的任务实体
MyRunnable myRunnable =new MyRunnable();
//创建多线程对象,来执行目标任务
Thread t1 = new Thread(myRunnable);
t1.start();
Thread t2 = new Thread(myRunnable);
t2.start();
for (int i=1;i<=10;i++){
System.out.println(Thread.currentThread().getName()+"执行"+i);
}
}
}
③代码结构布局:
运行结果:
代码如下:
SumCallable :
package com.aaa.test3;
//JUC
import java.util.concurrent.Callable;
/**
* 实现多线程编程方式三:实现Callable定义线程任务。可以实现分布式计算
* @author: hy
* @create: 2022-09-15 11:47:06
*/
public class SumCallable implements Callable {
int start;
int end;
public SumCallable(int start,int end){
this.start=start;
this.end=end;
}
@Override
public Object call() throws Exception {
int sum =0;
for (int i=start;i<=end;i++){
sum+=i;
System.out.println(Thread.currentThread().getName()+"执行"+i);
}
return sum;
}
}
Test:
package com.aaa.test3;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
/**
* @author: hy
* @create: 2022-09-15 11:50:18
*/
public class Test {
public static void main(String[] args) throws ExecutionException, InterruptedException {
//求1-100的和,通过Callable方式实现多线程的任务执行,分布运算并合并
//创建callable任务执行对象
FutureTask ft1=new FutureTask(new SumCallable(1,49));
FutureTask ft2=new FutureTask(new SumCallable(50,100));
//创建线程实体,关联任务对象
new Thread(ft1).start();
new Thread(ft2).start();
//线程执行完成之后,获取执行结果
int sum1=(int)ft1.get();
int sum2=(int)ft2.get();
System.out.println("ft1:"+sum1);
System.out.println("ft2:"+sum2);
System.out.println("两个线程求和的结果:"+(sum1+sum2));
}
}
异常:
①错误: 找不到或无法加载主类 com.aaa.test3.Test
解决:
删除target目录文件夹,然后运行代码。
线程池实现多线程???—代码:
MyRunnable :
package com.aaa.test4;
/**
* 定义线程任务
*/
public class MyRunnable implements Runnable{
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+" 执行任务");
}
}
Test :
package com.aaa.test4;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Test {
public static void main(String[] args) {
//创建线程任务对象
MyRunnable runnable = new MyRunnable();
//创建具有固定线程数的线程池
ExecutorService executorService = Executors.newFixedThreadPool(3);
//通过线程池执行线程任务:自动会使用线程池中的某个线程来执行任务
executorService.execute(runnable);
executorService.execute(runnable);
executorService.execute(runnable);
executorService.execute(runnable);
executorService.execute(runnable);
executorService.execute(runnable);
executorService.execute(runnable);
executorService.execute(runnable);
executorService.execute(runnable);
//关闭线程池
executorService.shutdown();
}
}
运行结果:
卖票线程—代码:
代码如下:
SalesTicketThread :
package com.aaa.test5;
/**
* 卖票线程
*/
public class SalesTicketThread extends Thread{
//售票员
private String saler;
//票数20
private int ticket =20;
//构造方法
public SalesTicketThread(String saler){
this.saler=saler;
}
/**
* 实现卖票任务
*/
@Override
public void run() {
//票数大于0,就继续卖票
while (ticket>0){
System.out.println(this.saler+"卖票一张,还剩:"+(--this.ticket)+"张");
}
}
}
Test :
package com.aaa.test5;
public class Test {
public static void main(String[] args) {
new SalesTicketThread("张三").start();
new SalesTicketThread("李四").start();
new SalesTicketThread("王五").start();
}
}
运行结果:
②代码结构布局:
运行结果:
代码如下:
SaleTiketRunnable :
package com.aaa.test6;
/**
* 定义卖票任务类
*/
public class SaleTiketRunnable implements Runnable{
//定义任务
private int ticket=20;
@Override
public void run() {
while (this.ticket>0){
System.out.println(Thread.currentThread().getName()+"卖票一张,还剩"+(--this.ticket)+"张");
}
}
}
Test :
package com.aaa.test6;
public class Test {
public static void main(String[] args) {
//创建任务对象
SaleTiketRunnable saleTiketRunnable = new SaleTiketRunnable();
//创建线程对象执行任务
new Thread(salesTicketRunnable,"孙悟空").start();
new Thread(salesTicketRunnable,"猪八戒").start();
new Thread(salesTicketRunnable,"沙僧").start();
}
}
运行结果:
定义/使用匿名内部类实现线程方法—代码:
IA :
package com.aaa.test7;
public interface IA {
void test();
}
Test :
package com.aaa.test7;
public class Test {
public static void main(String[] args) {
//IA ia = new TestACls();
//ia.test();
//定义匿名内部类实现接口
IA ia = new IA() {
@Override
public void test() {
System.out.println("这是匿名内部类实现接口方法");
}
};
ia.test();
}
}
TestACls :
package com.aaa.test7;
public class TestACls implements IA{
@Override
public void test() {
System.out.println("执行了test方法");
}
}
TestThread :
package com.aaa.test7;
public class TestThread {
public static void main(String[] args) {
//使用匿名内部类实现线程方法
Thread t1=new Thread("t1"){
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"执行任务....");
}
};
Thread t2=new Thread("t2"){
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"执行任务....");
}
};
Thread t3=new Thread("t3"){
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"执行任务....");
}
};
//设置线程优先级:1-10。不设置优先级时,优先级就是5
t1.setPriority(Thread.MAX_PRIORITY);
t2.setPriority(3);
t3.setPriority(Thread.MIN_PRIORITY);
t1.start();
t2.start();
t3.start();
}
}
运行结果:
线程礼让—代码:
Test :
package com.aaa.test8;
public class Test {
public static void main(String[] args) {
//线程礼让
Thread t1=new Thread("t1"){
@Override
public void run() {
for (int i=1;i<=10;i++){
System.out.println(Thread.currentThread().getName()+"执行了:"+i);
if(i==5){
//线程礼让:当前线程退出执行状态,重新参与时间片的争夺
Thread.yield();
}
}
}
};
Thread t2=new Thread("t2"){
@Override
public void run() {
for (int i=1;i<=10;i++){
System.out.println(Thread.currentThread().getName()+"执行了:"+i);
if(i==5){
//线程礼让:当前线程退出执行状态,重新参与时间片的争夺
Thread.yield();
}
}
}
};
Thread t3=new Thread("t3"){
@Override
public void run() {
for (int i=1;i<=10;i++){
System.out.println(Thread.currentThread().getName()+"执行了:"+i);
if(i==5){
//线程礼让:当前线程退出执行状态,重新参与时间片的争夺
Thread.yield();
}
}
}
};
t1.start();
t2.start();
t3.start();
}
}
运行结果:
创建Ping工具类,用于测试当前机器到目标主机的连通性—代码:
PingIPRunnable :
package com.aaa.test9;
import java.io.IOException;
/**
* 创建ping ip人物类
*/
public class PingIPRunnable implements Runnable{
private long start;
private String ip;
public PingIPRunnable(long start, String ip){
this.start=start;
this.ip=ip;
}
@Override
public void run() {
try {
PingUtil.ping(ip);
long end = System.currentTimeMillis();
System.out.println(Thread.currentThread().getName()+"花费时间:"+(end-start)/1000);
} catch (IOException e) {
e.printStackTrace();
}
}
}
PingUtil :
package com.aaa.test9;
import java.io.*;
/**
* 创建Ping工具类,用于测试当前机器到目标主机的连通性
*/
public class PingUtil {
/**
* ping目标主机,判断是否通畅
* @param ip
*/
public static void ping(String ip) throws IOException {
//获取程序运行时工具类
Runtime runtime = Runtime.getRuntime();
//执行ping命令,返回ping的执行程序对象
Process exec = runtime.exec("ping " + ip);
//执行ping操作,获取ping操作返回的输入流
InputStream inputStream = exec.getInputStream();
//构建缓冲输入流,对于ping的结果字符串内容
//字节字符转换流
InputStreamReader isr = new InputStreamReader(inputStream,"GBK");
//构建缓冲字符流
BufferedReader br =new BufferedReader(isr);
String str=null;
boolean isPingSuc=false;
while((str=br.readLine())!=null){
//System.out.println(str);
//如果返回结果包含TTL关键字,则认为ping通了
if(str.contains("TTL")){
isPingSuc=true;
break;
}
}
if(isPingSuc){
System.out.println("ping "+ip+" 能够ping通");
}else{
System.out.println("ping "+ip+" 不能ping通");
}
br.close();
isr.close();
inputStream.close();
}
}
Test :
package com.aaa.test9;
import java.io.IOException;
public class Test {
public static void main(String[] args) throws IOException {
//记录开始时间
long start = System.currentTimeMillis();
//ping 100-120之间的ip
for (int i=100;i<=120;i++){
PingUtil.ping("192.168.0."+i);
}
//记录结束时间
long end = System.currentTimeMillis();
System.out.println((end-start)/1000+"s");
}
}
Test2 :
package com.aaa.test9;
public class Test2 {
public static void main(String[] args) {
long start = System.currentTimeMillis();
//多线程方式,ping ip
for (int i=100;i<=120;i++){
new Thread(new PingIPRunnable(start,"192.168.0."+i)).start();
}
//long end = System.currentTimeMillis();
//System.out.println("main:"+(end-start)/1000);
//扩展:使用线程池的方式,实现ping ip的效果
}
}
运行结果:
同步代码块,对目标代码块加锁;定义同步方法,实现静态方法加锁—代码:
MyRunnable :
package com.aaa.test10;
public class MyRunnable implements Runnable{
@Override
public void run() {
for (int i=1;i<=10;i++){
show(i);
//synchronized:同步代码块,对目标代码块加锁
// synchronized (this) {
// System.out.println(Thread.currentThread().getName()+ " "+i + " -AAAA-");
// System.out.println(Thread.currentThread().getName()+ " "+i + "-BBBB-");
// System.out.println(Thread.currentThread().getName()+ " "+i + "-CCCC-");
// }
}
}
//synchronized:定义同步方法,实现静态方法加锁
public static synchronized void show(int i){
System.out.println(Thread.currentThread().getName()+ " "+i + " -AAAA-");
System.out.println(Thread.currentThread().getName()+ " "+i + "-BBBB-");
System.out.println(Thread.currentThread().getName()+ " "+i + "-CCCC-");
}
//synchronized:定义同步方法,实现实例方法加锁
// public synchronized void show(int i){
// System.out.println(Thread.currentThread().getName()+ " "+i + " -AAAA-");
// System.out.println(Thread.currentThread().getName()+ " "+i + "-BBBB-");
// System.out.println(Thread.currentThread().getName()+ " "+i + "-CCCC-");
// }
}
Test :
package com.aaa.test10;
public class Test {
public static void main(String[] args) {
MyRunnable myRunnable = new MyRunnable();
//创建3个线程执行任务
new Thread(myRunnable).start();
new Thread(myRunnable).start();
new Thread(myRunnable).start();
}
}
运行结果:
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/118033.html