尝试在多线程环境中的条件帐户之间进行转移,我的方法有多真实,我错在哪里?
按照计划,我在主线程中创建了一个新的线程,在这个新线程中初始化了一个类型为Transfer的新类,然后我从数据库中获取了2个帐户的数据,我随机确定了要随机传输的数量。我翻译并将更改写回数据库。账户中所有资金的总和必须保持正确。也就是说,如果我们有50个账户,每个账户1000元(总共50000元),那么在所有交易之后,应该不会有更多,也不会超过50000元。
如果线程不超过5-10个,并且线程Hibernate时间超过500毫秒,则下面描述的方法有效。也许我解决问题的方法不对。我试过用tryLock,结果是一样的。总的来说,钱会变成正数,然后变成负数。
另外,我正试着在Hibernate上这样做。< br >我所拥有的:< br> 1。类某银行账户- Account (@Entity)
2。类TransferThread扩展了Thread
3。类别转移-处理转移4。主类
现在它看起来像这样:类帐户(设置/获取(我不在这里写它们,但它们在那里)):
public class Account {
private int id;
private int money;
public Account() {
}
public void widrawal(int sum) {
money += sum;
}
public void send(int sum) {
money -= sum;
}
}
类TransferThread(根据想法,完成事务并随机Hibernate一段时间(10次)):
public class TransferThread extends Thread {
Transfer transfer= new Transfer();
AtomicInteger atomicInteger = new AtomicInteger();
public void run() {
atomicInteger.set(10);
while (atomicInteger.get() > 0) {
//thread sleep for random time
int a = (int) (Math.random() * (500 - 100)) + 100;
try {
transfer.transaction();
atomicInteger.getAndDecrement();
Thread.sleep(a);
} catch (InterruptedException e) {
}
}
}
}
类别转移:
public class Transfer {
public void transaction() throws InterruptedException {
int sumSpis = (int) (Math.random() * 100) + 10;
int ranAccount1 = (int) (Math.random() * 50) + 1;
int ranAccount2 = (int) (Math.random() * 50) + 1;
Account a1 = null;
Account a2 = null;
a1 = HibernateSessionFactoryUtil.getSessionFactory().openSession().get(Account.class, ranAccount1);
a2 = HibernateSessionFactoryUtil.getSessionFactory().openSession().get(Account.class, ranAccount2);
int fromId = a1.getId();
int toId = a2.getId();
if (fromId < toId) {
synchronized (a1) {
synchronized (a2) {
transfer(a1, a2, sumSpis);
}
}
} else {
synchronized (a2) {
synchronized (a1) {
transfer(a1, a2, sumSpis);
}
}
}
System.out.println("amount: " + sumSpis);
}
public void transfer(Account account1, Account account2, int sum) {
if (account1.getId() == account2.getId()) {
System.out.println("same IDs");
return;
}
if (account1.getMoney() < sum) {
System.out.println("not enough account funds");
return;
}
account1.widrawal(sum);
account2.send(sum);
Session session = HibernateSessionFactoryUtil.getSessionFactory().openSession();
Transaction tx = session.beginTransaction();
session.update(account1);
session.update(account2);
tx.commit();
session.close();
}
}
动作的顺序应该如下:获取会话、启动数据库事务、从数据库获取acc1的数据、从数据库获取acc2的数据、转账、将acc1的数据保存到数据库、将acc2的数据保存到数据库、提交数据库事务。
在您的代码中,您从数据库中获取帐户数据,并将新数据保存在单独的会话中,这意味着事务也是单独的。在从数据库获取和保存到数据库I之间,一个线程和另一个线程可能已经更新了这些帐户的数据,而您正在用过时的数据覆盖这些数据。
问题内容: 我需要一个解决方案来正确停止Java中的线程。 我有实现Runnable接口的类: 我有启动和停止线程的类: 但是当我关闭时,我在类中得到了异常: 我正在使用JDK 1.6。所以问题是: 如何停止线程并且不引发任何异常? PS我不想使用;方法,因为它已过时。 问题答案: 在类中,你需要一种设置标志的方法,该标志通知线程它将需要终止,类似于你刚刚在类范围中使用的变量。 当你希望停止线程时
我有一个耗时的任务,我想在用户输入“abort”时手动中止它。 可运行:
我试图了解更多关于java线程转储的信息。我正在使用JBOSS EAP 4.3。 目前,我在我的一个环境中面临性能问题。突然,CPU利用率上升到700%。我把线程转储了,它是一个巨大的文件。 我在我的threaddump中发现了很多下面等待的线程条目。 我想从上面的等待线程中理解。是什么导致CPU利用率上升?
问题内容: 我有用于在Java中创建线程的此类 控制台显示以下文本作为输出 我的代码创建了新线程: 我的问题是:为什么返回正确的线程名却返回另一个? 问题答案: 为什么要返回正确的线程名称而又返回其他? 您的课程,但随后您通过调用以下内容开始: 这是不正确的。这意味着创建的线程实际是 不 一样的。 应该实现而 不是 扩展线程。您的代码可以工作,因为线程也是可运行的。 因为有两个线程对象,所以当您调
但这一个也不起作用。正确的答案是加入线程并删除2个睡眠: 我的问题是:为什么我的答案都不能被接受?我的实验室领导问,但他不能给我一个答案。在家里编写了测试代码,它似乎工作得很好。提前感谢您的帮助!
问题内容: 我在掌握如何正确处理从以多线程方式使用Boost Asio的多线程程序创建子进程方面遇到一些麻烦。 如果我理解正确,那么在Unix世界中启动子进程的方法是先调用,然后调用。另外,如果我理解正确,则调用将复制所有文件描述符,依此类推,除非标记为,否则需要 在子进程中将其 关闭(从而在调用时被原子关闭)。 Boost Asio需要在被调用时得到通知,以便通过调用正确运行。但是,在多线程程序