多线程模拟上报完善
parent
1aafbe78b9
commit
2473b1c944
|
@ -1,9 +1,8 @@
|
||||||
package com.muyu.common;
|
package com.muyu.common;
|
||||||
|
|
||||||
import com.muyu.vehicle.MyThread;
|
|
||||||
|
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
import java.util.concurrent.ScheduledExecutorService;
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
|
import java.util.concurrent.ScheduledFuture;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -18,8 +17,15 @@ public class ThreadPool {
|
||||||
*/
|
*/
|
||||||
private static final ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(1);
|
private static final ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(1);
|
||||||
|
|
||||||
public static void submit (Runnable thread){
|
public static ScheduledFuture<?> submit (Runnable thread){
|
||||||
// 参数分别是: 任务, 多久后开始执行, 每隔多久执行一次(周期),时间单位
|
// 参数分别是: 任务, 多久后开始执行, 每隔多久执行一次(周期),时间单位
|
||||||
scheduledThreadPool.scheduleAtFixedRate(thread, 0,1, TimeUnit.SECONDS);
|
return scheduledThreadPool.scheduleAtFixedRate(thread, 0, 1, TimeUnit.SECONDS);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 关闭线程池
|
||||||
|
*/
|
||||||
|
public static void shutdown() {
|
||||||
|
scheduledThreadPool.shutdown();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,37 +0,0 @@
|
||||||
package com.muyu.vehicle;
|
|
||||||
|
|
||||||
public class MyThread implements Runnable {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 设置是否暂停
|
|
||||||
*/
|
|
||||||
private volatile boolean isPaused;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
if (!isPaused){
|
|
||||||
System.out.println(System.currentTimeMillis());
|
|
||||||
}else {
|
|
||||||
System.out.println("线程暂停");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 暂停线程
|
|
||||||
*/
|
|
||||||
public void pause() {
|
|
||||||
isPaused = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 开始线程
|
|
||||||
*/
|
|
||||||
public void resume() {
|
|
||||||
isPaused = false;
|
|
||||||
synchronized (this) {
|
|
||||||
notify(); // 唤醒线程
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,6 +1,13 @@
|
||||||
package com.muyu.vehicle;
|
package com.muyu.vehicle;
|
||||||
|
|
||||||
import com.muyu.common.ThreadPool;
|
import com.muyu.common.ThreadPool;
|
||||||
|
import com.muyu.domain.Vehicle;
|
||||||
|
import com.muyu.vehicle.core.LocalContainer;
|
||||||
|
import com.muyu.vehicle.model.VehicleData;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.concurrent.CountDownLatch;
|
||||||
|
|
||||||
import static java.lang.Thread.sleep;
|
import static java.lang.Thread.sleep;
|
||||||
|
|
||||||
|
@ -11,47 +18,85 @@ import static java.lang.Thread.sleep;
|
||||||
*/
|
*/
|
||||||
public class Test {
|
public class Test {
|
||||||
|
|
||||||
|
public static CountDownLatch countDownLatch = new CountDownLatch(2);
|
||||||
public static void main(String[] args) throws InterruptedException {
|
public static void main(String[] args) throws InterruptedException {
|
||||||
|
|
||||||
|
String vin1 = "VIN123456789123456", vin2 = "VIN123456789166666";
|
||||||
|
init(vin1);
|
||||||
|
init(vin2);
|
||||||
|
new Thread(new TestThread(vin1)).start();
|
||||||
|
new Thread(new TestThread(vin2)).start();
|
||||||
|
countDownLatch.await();
|
||||||
|
ThreadPool.shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
MyThread thread = new MyThread();
|
public static void init(String vin){
|
||||||
ThreadPool.submit(thread);
|
Vehicle vehicle = Vehicle.builder()
|
||||||
new Thread(() -> {
|
.vin(vin)
|
||||||
|
.createTime(new Date())
|
||||||
|
.remainingBattery(new BigDecimal("45000"))
|
||||||
|
.batteryLevel(new BigDecimal("50000"))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
VehicleInstance vehicleInstance = new VehicleInstance();
|
||||||
|
vehicleInstance.setVehicle(vehicle);
|
||||||
|
vehicleInstance.setVehicleData(VehicleData.vehicleBuild(vehicle));
|
||||||
|
LocalContainer.setVehicleInstance(vehicleInstance);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class TestThread implements Runnable{
|
||||||
|
|
||||||
|
private String vin ;
|
||||||
|
|
||||||
|
public TestThread(String vin) {
|
||||||
|
this.vin = vin;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When an object implementing interface {@code Runnable} is used
|
||||||
|
* to create a thread, starting the thread causes the object's
|
||||||
|
* {@code run} method to be called in that separately executing
|
||||||
|
* thread.
|
||||||
|
* <p>
|
||||||
|
* The general contract of the method {@code run} is that it may
|
||||||
|
* take any action whatsoever.
|
||||||
|
*
|
||||||
|
* @see Thread#run()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
VehicleInstance vehicleIns = LocalContainer.getVehicleInstance(vin);
|
||||||
|
vehicleIns.initVehicleThread();
|
||||||
try {
|
try {
|
||||||
sleep(3000);
|
sleep(3000);
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
thread.pause();
|
vehicleIns.startSend();
|
||||||
}).start();
|
|
||||||
|
|
||||||
/*new Thread(() -> {
|
|
||||||
try {
|
|
||||||
sleep(5000);
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
System.out.println("执行了五秒,等待五秒,在开始");
|
|
||||||
try {
|
|
||||||
synchronized (thread){
|
|
||||||
thread.wait();
|
|
||||||
}
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
System.out.println("等待了五秒,现在开始,3秒后杀死");
|
|
||||||
synchronized (thread){
|
|
||||||
thread.notify();
|
|
||||||
}
|
|
||||||
try {
|
try {
|
||||||
sleep(3000);
|
sleep(3000);
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
synchronized (thread){
|
vehicleIns.pauseSend();
|
||||||
thread.interrupt();
|
|
||||||
|
try {
|
||||||
|
sleep(3000);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
System.out.println("停止成功" + thread.isAlive());
|
vehicleIns.startSend();
|
||||||
}).start();*/
|
|
||||||
|
try {
|
||||||
|
sleep(3000);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
vehicleIns.stopSend();
|
||||||
|
|
||||||
|
Test.countDownLatch.countDown();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,105 @@
|
||||||
|
package com.muyu.vehicle;
|
||||||
|
|
||||||
|
import com.muyu.common.ThreadPool;
|
||||||
|
import com.muyu.domain.Vehicle;
|
||||||
|
import com.muyu.vehicle.model.VehicleData;
|
||||||
|
import com.muyu.vehicle.thread.VehicleThread;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.extern.log4j.Log4j2;
|
||||||
|
|
||||||
|
import java.util.concurrent.ScheduledFuture;
|
||||||
|
|
||||||
|
import static java.lang.Thread.sleep;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author DongZeLiang
|
||||||
|
* @version 1.0
|
||||||
|
* @description 车辆实例
|
||||||
|
* @date 2023/11/16
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Log4j2
|
||||||
|
@Builder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class VehicleInstance {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 车辆
|
||||||
|
*/
|
||||||
|
private Vehicle vehicle;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 实例数据
|
||||||
|
*/
|
||||||
|
private VehicleData vehicleData;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 车辆工作线程
|
||||||
|
*/
|
||||||
|
private VehicleThread vehicleThread;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 线程提交回调
|
||||||
|
*/
|
||||||
|
private ScheduledFuture<?> scheduledFuture;
|
||||||
|
|
||||||
|
|
||||||
|
/***
|
||||||
|
* 获取当前车辆VIN
|
||||||
|
* @return VIN
|
||||||
|
*/
|
||||||
|
public String getVin(){
|
||||||
|
return this.vehicle.getVin();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 初始化线程
|
||||||
|
*/
|
||||||
|
public void initVehicleThread(){
|
||||||
|
VehicleThread vehicleThread = new VehicleThread();
|
||||||
|
vehicleThread.setVehicleInstance(this);
|
||||||
|
this.setVehicleThread(vehicleThread);
|
||||||
|
this.vehicleThread.pause();
|
||||||
|
ScheduledFuture<?> scheduledFuture = ThreadPool.submit(vehicleThread);
|
||||||
|
this.setScheduledFuture(scheduledFuture);
|
||||||
|
log.info("初始化车辆上报模拟线程开始:[{}]", this.getVin());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 开始上报线程
|
||||||
|
*/
|
||||||
|
public void startSend(){
|
||||||
|
this.vehicleThread.resume();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 暂停上报线程
|
||||||
|
*/
|
||||||
|
public void pauseSend(){
|
||||||
|
this.vehicleThread.pause();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 结束发送
|
||||||
|
*/
|
||||||
|
public void stopSend(){
|
||||||
|
this.vehicleThread.stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 取消执行
|
||||||
|
*/
|
||||||
|
public void cancelExecution(){
|
||||||
|
scheduledFuture.cancel(true);
|
||||||
|
this.vehicleThread = null;
|
||||||
|
this.scheduledFuture = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,8 +1,6 @@
|
||||||
package com.muyu.vehicle.core;
|
package com.muyu.vehicle.core;
|
||||||
|
|
||||||
import com.muyu.domain.Vehicle;
|
import com.muyu.vehicle.VehicleInstance;
|
||||||
import com.muyu.vehicle.model.VehicleData;
|
|
||||||
import com.muyu.vehicle.model.VehicleInstance;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -21,19 +19,22 @@ public class LocalContainer {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 添加车辆
|
* 添加车辆
|
||||||
* @param vehicle 车辆信息
|
* @param vehicleInstance 车辆信息
|
||||||
*/
|
*/
|
||||||
public static void setVehicle(Vehicle vehicle){
|
public static void setVehicleInstance(VehicleInstance vehicleInstance){
|
||||||
String vin = vehicle.getVin();
|
String vin = vehicleInstance.getVehicle().getVin();
|
||||||
VehicleInstance vehicleInstance = vehicleDataMap.get(vin);
|
if (!vehicleDataMap.containsKey(vin)) {
|
||||||
if (vehicleInstance == null){
|
vehicleDataMap.put(vin, vehicleInstance);
|
||||||
vehicleDataMap.put(vin,
|
|
||||||
VehicleInstance.builder()
|
|
||||||
.vehicleData(VehicleData.vehicleBuild(vehicle))
|
|
||||||
.vehicle(vehicle)
|
|
||||||
.build()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取车辆信息
|
||||||
|
* @param vin vin
|
||||||
|
* @return 车辆实例
|
||||||
|
*/
|
||||||
|
public static VehicleInstance getVehicleInstance(String vin){
|
||||||
|
return vehicleDataMap.get(vin);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,7 +34,7 @@ public class VehicleConfiguration implements ApplicationRunner {
|
||||||
while (true){
|
while (true){
|
||||||
Page<Vehicle> vehiclePage = vehicleService.page(new Page<Vehicle>(page++, pageSize));
|
Page<Vehicle> vehiclePage = vehicleService.page(new Page<Vehicle>(page++, pageSize));
|
||||||
List<Vehicle> records = vehiclePage.getRecords();
|
List<Vehicle> records = vehiclePage.getRecords();
|
||||||
records.forEach(LocalContainer::setVehicle);
|
// records.forEach(LocalContainer::setVehicle);
|
||||||
log.info("第[{}]页,[{}]条", page, records.size());
|
log.info("第[{}]页,[{}]条", page, records.size());
|
||||||
if (records.size() < pageSize){
|
if (records.size() < pageSize){
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -1,35 +0,0 @@
|
||||||
package com.muyu.vehicle.model;
|
|
||||||
|
|
||||||
import com.muyu.domain.Vehicle;
|
|
||||||
import lombok.AllArgsConstructor;
|
|
||||||
import lombok.Builder;
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.NoArgsConstructor;
|
|
||||||
|
|
||||||
import static java.lang.Thread.sleep;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author DongZeLiang
|
|
||||||
* @version 1.0
|
|
||||||
* @description 车辆实例
|
|
||||||
* @date 2023/11/16
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
@Builder
|
|
||||||
@NoArgsConstructor
|
|
||||||
@AllArgsConstructor
|
|
||||||
public class VehicleInstance {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 车辆
|
|
||||||
*/
|
|
||||||
private Vehicle vehicle;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 实例数据
|
|
||||||
*/
|
|
||||||
private VehicleData vehicleData;
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
|
@ -0,0 +1,66 @@
|
||||||
|
package com.muyu.vehicle.thread;
|
||||||
|
|
||||||
|
import com.muyu.vehicle.VehicleInstance;
|
||||||
|
import lombok.extern.log4j.Log4j2;
|
||||||
|
|
||||||
|
@Log4j2
|
||||||
|
public class VehicleThread implements Runnable {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否停止线程
|
||||||
|
*/
|
||||||
|
private volatile boolean isStop = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置是否暂停
|
||||||
|
*/
|
||||||
|
private volatile boolean isPaused;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 车辆实例对象
|
||||||
|
*/
|
||||||
|
private VehicleInstance vehicleInstance;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
if (!isStop){
|
||||||
|
if (!isPaused){
|
||||||
|
System.out.println(System.currentTimeMillis());
|
||||||
|
}else {
|
||||||
|
log.info("暂停模拟和上报:[{}]", this.vehicleInstance.getVin());
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
log.info("终止模拟和上报:[{}]", this.vehicleInstance.getVin());
|
||||||
|
vehicleInstance.cancelExecution();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 暂停线程
|
||||||
|
*/
|
||||||
|
public void pause() {
|
||||||
|
isPaused = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 开始线程
|
||||||
|
*/
|
||||||
|
public void resume() {
|
||||||
|
isPaused = false;
|
||||||
|
synchronized (this) {
|
||||||
|
notify(); // 唤醒线程
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 停止方法
|
||||||
|
*/
|
||||||
|
public void stop(){
|
||||||
|
this.isStop = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setVehicleInstance(VehicleInstance vehicleInstance) {
|
||||||
|
this.vehicleInstance = vehicleInstance;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue