对不起,如果这个问题可能看起来很幼稚,但我遇到过需要管理电子商务商店数据库中产品数量的情况.
有一个带有整数变量的Product类,productCount它表示数据库中可供该站点用户看到的可用产品数.现在这个类可以被多个线程访问,或者可以说电子商务站点的几个用户.每个人都在添加或删除产品到他的购物车.
正在使用的ORM框架是休眠
示例代码
@Entity
@Table
class Product{
@Column
private int productCount;
public void addProductToCart(){
// decrements the product count by 1 & updates the database
}
public void removeTheProductFromTheCart(){
// increments the product count by 1 & updates the database
}
Run Code Online (Sandbox Code Playgroud)
从代码中可以清楚地看出,我需要对数据库中的产品计数进行并发检查,以防止丢失更新.
此外,如果多个用户尝试在数据库中仅添加单个左侧产品.应该将产品添加到哪个用户的购物车?
我对此做了一点研究
我找到的可能方法是
为Product创建单例类.这将确保整个应用程序中只有一个产品实例可用.
同步addProductToCart& removeTheProductFromTheCart方法.这将只允许一个线程更新产品计数并一次更新数据库.
使用数据库并发控制应用一些db事务隔离级别,乐观/悲观锁定productCount.我使用mysql的默认隔离级别是REPEATABLE_READ.
处理这个问题的最佳方法是什么?
当您在同一个文件上同时打开两个(或更多)FileOutputStream时会发生什么?
在Java的API这样说:
特别是某些平台允许一次只打开一个FileOutputStream(或其他文件写入对象)来写文件.
我猜Windows不是这样的平台,因为我有两个线程读取一些大文件(每个都是不同的文件),然后将其写入相同的输出文件.抛出没有异常,文件被创建并且似乎包含来自两个输入文件的块.
附带问题:
对 Java 非常陌生,所以我现在感觉像个孩子。我猜学习一门新语言的乐趣。
这是我的发票类:
public class Invoice {
//member inits
private int numberOfInvoices = 0;
private String companyName;
private double amountDue;
private String chargeDate;
private static int invoiceNumber = 0;
//constructor
public Invoice(String _companyName, double _amountDue, String _chargeDate)
{
numberOfInvoices++;
companyName = _companyName;
amountDue = _amountDue;
chargeDate = _chargeDate;
invoiceNumber = numberOfInvoices;
}
//getters
public String getCompanyName()
{
return companyName;
}
public double getAmountDue()
{
return amountDue;
}
public String getChargeDate()
{
return chargeDate;
}
public int getInvoiceNumber()
{
invoiceNumber …Run Code Online (Sandbox Code Playgroud) 我需要一种方法来只允许一个线程修改与服务票证相关的数据。可能有多个线程同时尝试修改票证数据。
下面是我的方法的简化版本。有一个更好的方法吗?也许使用 java.util.concurrent 包?
public class SomeClass1
{
static final HashMap<Integer, Object> ticketLockMap = new HashMap<Integer, Object>();
public void process(int ticketNumber)
{
synchronized (getTicketLock(ticketNumber))
{
// only one thread may modify ticket data here
// ... ticket modifications here...
}
}
protected static Object getTicketLock(int ticketNumber)
{
Object ticketLock;
// allow only one thread to use map
synchronized (ticketLockMap)
{
ticketLock = ticketLockMap.get(ticketNumber);
if (ticketLock == null)
{
// first time ticket is locked
ticketLock = new Object();
ticketLockMap.put(ticketNumber, ticketLock); …Run Code Online (Sandbox Code Playgroud) 在处理多线程程序时,我观察到了非常奇怪的行为.
当Integer对象用作锁时,似乎多个线程可以处于同步块中.甚至认为这是不可预期的.
如果我在下面的程序中使用任何其他静态成员,如's','o'和'c',则按预期工作.
码-
public class MyThread extends Thread{
private static Integer ii=1; //Works fine
private static Integer i=1;
private static String s="1"; //Works fine
private static Object o= new Object(); //Works fine
private static Class<MyThread> c= MyThread.class; //Works fine
public void run(){
synchronized(i){
System.out.print(i++ +" ");
System.out.print(i+" ");
}
}
public static void main(String[] str) throws InterruptedException{
for(int i=0;i<100;i++){
MyThread t= new MyThread();
t.start();
}
Thread.sleep(100);
System.out.println();
MyThread t= new MyThread();
t.start();t.join();
if(i!=102)
System.out.println("fail");
}
}
Run Code Online (Sandbox Code Playgroud)
输出 -
2 …Run Code Online (Sandbox Code Playgroud) 我有一个Web应用程序,我正在使用Oracle数据库,我有一个基本上像这样的方法:
public static void saveSomethingImportantToDataBase(Object theObjectIwantToSave) {
if (!methodThatChecksThatObjectAlreadyExists) {
storemyObject() //pseudo code
}
// Have to do a lot other saving stuff, because it either saves everything or nothing
commit() // pseudo code to actually commit all my changes to the database.
}
Run Code Online (Sandbox Code Playgroud)
现在没有任何类型的同步,所以n个线程当然可以自由地访问这个方法,当2个线程进入这个方法同时检查时会出现问题,当然还没有任何东西,然后他们都可以提交事务,创建重复的对象.
我不想在我的数据库中使用唯一的密钥标识符来解决这个问题,因为我不认为我应该抓住它SQLException.
我也无法在提交之前检查,因为不仅有几个检查1,这将花费相当长的时间.
我对锁和线程的体验是有限的,但我的想法基本上是将这个代码锁定在它接收的对象上.我不知道例如说我收到一个Integer对象,并且我用值1锁定我的Integer,是否只会阻止另一个值为1的Integer进入,而所有其他线程value != 1都可以自由进入?这是怎么回事?
此外,如果这是它的工作原理,锁对象如何比较?它是如何确定它们实际上是同一个对象的?关于这一点的好文章也将受到赞赏.
你怎么解决这个问题?
我正在进入Java多线程.我对C/C++ pthreads非常熟悉,但是我遇到了Java notify()和wait()函数的问题.
我知道IllegalMoinitorStateException只有当一个不"拥有"(又名没有同步)的线程调用notify/wait时才会抛出一个.
在编写我的应用程序时,我遇到了这个问题.我用以下测试代码隔离了问题:
public class HelloWorld
{
public static Integer notifier = 0;
public static void main(String[] args){
notifier = 100;
Thread thread = new Thread(new Runnable(){
public void run(){
synchronized (notifier){
System.out.println("Notifier is: " + notifier + " waiting");
try{
notifier.wait();
System.out.println("Awake, notifier is " + notifier);
}
catch (InterruptedException e){e.printStackTrace();}
}
}});
thread.start();
try{
Thread.sleep(1000);
}
catch (InterruptedException e){
e.printStackTrace();
}
synchronized (notifier){
notifier = 50;
System.out.println("Notifier is: " + notifier …Run Code Online (Sandbox Code Playgroud) 我想同步一段代码,但不想简单地锁定实现类(this).
有问题的代码块是一个接收id的方法的一部分.
如果传入方法的id包含在类的列表中,我想禁止新线程进入块...如果它不在列表中,则实体可以自由操作,因此线程将是允许进入街区......
有没有直接的方法来做到这一点?
如何在方法参数值上提供同步?
使用“相同”参数值A的所有方法调用都应该同步。即使使用A的调用已在等待中,也可以访问具有不同参数值的方法调用,例如B。B的下一个并发调用还必须等待第一个B被释放。
我的用例:我想在ID级别上同步对JPA实体的访问,但要避免悲观锁定,因为我需要某种队列。用于锁定的“ 键 ”旨在作为实体ID-实际上是Java Long类型。
protected void entityLockedAccess(SomeEntity myEntity) {
//getId() returns different Long objects so the lock does not work
synchronized (myEntity.getId()) {
//the critical section ...
}
}
Run Code Online (Sandbox Code Playgroud)
我阅读了有关锁定对象的信息,但不确定如何适合我的情况。在顶层,我想管理对执行关键代码的应用程序的特定REST调用。
谢谢克里斯
此问题基于 Synchronizing on Integer值.
解决方案似乎很好只有小问题它没有解决关于如何从中删除值的问题ConcurrentHashMap.
所以要解决我在下面的程序
import java.util.concurrent.ConcurrentHashMap;
public class Example {
private final ConcurrentHashMap<Integer, Integer> concurrentHashMap = new ConcurrentHashMap<Integer, Integer>();
public void doSomething(int i) {
synchronized (getLockForId(i)) {
concurrentHashMap.remove(i);
}
}
public Integer getLockForId(int id) {
concurrentHashMap.putIfAbsent(id, id); // I want to replace these two
// operation with single one
// since it seems the cause of
// NPE
return concurrentHashMap.get(id);
}
public static void main(String[] args) {
final Example example = new Example();
new Thread(new …Run Code Online (Sandbox Code Playgroud) java ×10
concurrency ×3
database ×1
file-io ×1
java-8 ×1
locking ×1
portability ×1
rest ×1
synchronized ×1