如何使用jdbc将多线程添加到应用程序中



我是多线程的新手,甚至不知道如何处理应用程序中的线程。该应用程序是一个控制台游戏。玩家选择英雄、部落和行动。黄金因各种行为而被记入财政部。你可以从口袋里添加,完成任务或赢得战斗。每个动作都是一个单独的类。所有操作都保存到数据库中。这是创建操作对象的代码,它还保存了对部落金库的更改

public class OperationService {
OperationDAO operationDAO = new OperationDAO();
private static ClanService clanService = new ClanService();
public void createOperation(String reason, int sum) {
Hero currentHero = CurrentHero.getCurrentHero();
Clan currentClan = CurrentHero.getClan();
LocalDateTime currentDateTime = LocalDateTime.now();
Operation operation = new Operation();
operation.setClan(currentClan);
operation.setHero(currentHero);
operation.setReason(reason);
operation.setSum(sum);
operation.setAmountBefore(currentClan.getGold());
operation.setAmountAfter(currentClan.getGold() + sum);
operation.setDateTime(currentDateTime);
operationDAO.save(operation);
clanService.changeAmount(sum);
}

问题是,这意味着许多玩家将同时执行不同的动作,并改变他们部落的金库。根据任务,需要进入多线程,但要正确显示之前和之后的族库金额。

随着游戏的推出,我还创建了一个线程,它从不同的类中调用了一大串方法。

public class ThreadGame extends Thread {
HeroService heroService = new HeroService();
public ThreadGame() {
this.start();
}
@Override
public void run() {
heroService.startGame();
}
}

问题1。链中的方法也可以被视为线程吗?还是他们不再是其中的一部分

我还尝试为我的应用程序创建测试,但有些操作没有保存在数据库中,同步也没有帮助。

public class Test extends Thread {
HeroDAO heroDAO = new HeroDAO();
OperationService operationService = new OperationService();
@Override
public void run() {
Hero hero1 = heroDAO.findById(4L);
operationService.createOperationForTest(hero1, "Победа в бою", 20);
operationService.createOperationForTest(hero1, "Победа в бою", 20);
}
}
public class App {
public static void main(String[] args) {
Test test = new Test();
Test test1 = new Test();
test.start();
test1.start();
}
}

同步了createOperationForTest方法,但数据仍然存储不正确。问题2。在哪里指定synchronized

  1. run()函数中编写的所有代码都将在执行thread.start();时创建的线程中运行

例如:在你的课程ThreadGame中,你有这样的功能:

@Override
public void run() {
System.out.println("Hello, I'm a thread");
heroService.startGame();
}

执行.start()函数时,将创建一个线程,然后该线程将执行run()函数中的代码。因此,在这种情况下;你好,我是线程"然后执行您的CCD_ 6函数。您在startGame()中编写的所有代码都将在此线程上执行。请注意,您可以在一个线程内创建另一个线程。

  1. 存在线程以提供异步执行。如果你需要让一个线程等待另一个线程完成某件事,你可以使用Semaphores!这里有一个链接来了解更多关于信号量的信息

Elisaveta。

要了解多线程,我建议:

  1. 关于并发的Java官方教程
  2. Java并发在实践中的应用

但简而言之,线程可以让我们并行运行一些东西,并使用CPU的多个核心。

线程使用的一个很好的例子是web服务器
web服务器接收HTTP请求,并对每个请求返回HTTP响应
为了使用所有可用的CPU核心,web服务器使用几个线程(通常称为"线程池")
当新的HTTP请求到达web服务器时,主线程将请求处理任务委托给线程池中的一个空闲线程
线程在完成请求处理并发送HTTP响应之前一直处于繁忙状态,但在此之后,它再次变为空闲状态,可用于处理新的请求。

在Java中,使用线程池并行执行任务是一种常见的模式。

在您的情况下,可以使用线程并行保存新操作
类似这样的东西:

public class App {

final HeroDAO heroDAO = new HeroDAO();
final OperationService operationService = new OperationService();
final ExecutorService threadPool;

App() {
var numCores = Runtime.getRuntime().availableProcessors();
threadPool = Executors.newFixedThreadPool(numCores);
}

void saveNewOperation(long heroId, String reason, int sum) {
threadPool.submit(() -> {
var hero = heroDAO.findById(heroId);
operationService.createOperationForTest(hero, reason, sum);
});
}

void stop() throws InterruptedException {
threadPool.shutdown();
threadPool.awaitTermination(10, TimeUnit.SECONDS);
threadPool.shutdownNow();
}
public static void main(String[] args) throws InterruptedException {
var app = new App();
try {
app.saveNewOperation(4L, "Победа в бою", 20);
app.saveNewOperation(5L, "Победа в бою", 30);
app.saveNewOperation(6L, "Победа в бою", 40);
app.saveNewOperation(7L, "Победа в бою", 50);
} finally {
app.stop();
}
}
}

对于多线程,您应该小心使用静态变量(代码中的CurrentHero似乎是存储当前英雄的静态变量)
当您并行处理两个操作时,可能会有两个当前英雄
在多线程应用程序中,此类信息通常显式传递给方法(有时将多个属性分组在一个context对象中,该对象通常是为每个属性名称存储对象值的Map<String,Object>)。

当我们希望保证某个代码块同时只能由一个线程执行时,就会使用synchronized
我们经常使用synchronized来保护与某些共享资源一起工作的代码(例如,与数据库的已建立连接可能只能由一个线程同时使用)
此外,synchronized允许我们保证某组操作以原子方式发生(即,这些操作不会与并行线程中的操作交错)。

对于您的示例,可能需要synchronized

  • 围绕CCD_ 15:这里我们有一个共享资源"财政部">
    如果操作changeAmount在内部由多个操作组成,那么您可能希望以原子方式执行这些操作
  • 关于CCD_ 17:这里我们有一个共享资源";操作存储器">
    同样,如果save在内部由多个操作组成,那么您可能希望以原子方式执行它们
    此外,如果operationDAO使用到数据库的内部连接,则此连接可能需要一次由一个线程使用
  • 周围
    operationDAO.save(operation);
    clanService.changeAmount(sum);
    
    如果您希望这两个操作作为单个原子块执行

相关内容

最新更新