多线程并发访问数据库中不同记录时应该采用什么办法

多线程并发访问数据库中不同记录时应该采用什么办法,第1张

多个线程在访问同一个数据库中的记录的时候,在大并发的情况下,一定要做好事务机制。要不然后果还是很扎心的。可能遇到这样的问题的时候首先想到的就是同步锁机制了。

并发产生的情况

以我的平时工作的经验来说,凡是涉及多线程的并发访问的问题一定要小心。因为一不小心就会产生死锁问题。平时编程的时候更要多注意这方面的问题。我们可以产生问题的情况是复杂的,两个线程争同一个对象会有问题如果你只静态的方法,简单的逻辑不是问题,但是如果你的线程是修改静态变量的值,那应该是线程问题造成的。

java多线程并发

最经典的多并发的情况就是生产者和消费者的问题了吧。之前在学校学习 *** 作系统的时候,经常因为类似的并发 *** 作的问题想很久。后来工作的时候真正的实践以后,更能很好的体会到并发线程 *** 作的难度。java是线程安全的,即对任何方法(包括静态方法)都可以不考虑线程冲突,但有一个前提,就是不能存在全局变量。如果存在全局变量,则需要使用同步机制。

并发连接数据库

其实在实际项目开发汇总,首先要做的就是避免多个线程共用一个数据库连接,这样会很容易出问题,最好是一个线程一个连接。在必要的时候需要线程同步或存储过程加锁。如果有比较复杂的事务 *** 作的话就需要加锁了,如果不加的话就会出现你说的脏读、死锁等问题。

没看懂,个人觉得你的一条记录就是一个配置信息,对应一个配置对象

数据库就是存储记录的地方, 每次从数据库取自然就会取到最新的所有记录,也就是所有的配置项。

你的配置是纵向增加的,1个配置、2个配置、、n个配置,没什么问题,数据库增加一行就行

配置是横向增加的,那你的配置对象就要变化了

而且这个跟线程池也没什么关系吧,或者你只是想来实现一个定时任务不断刷新,springboot注入个@Schedule也行

线程和车票应该隔离,即车票库存和线程是没有关系的在构造Sell的时候把总的车票库存,车票单独写一个单例类来进行管理,并且获取车票写成一个函数,该函数要是同步的,使用synchronized关键字不要简单通过ticket--来使得车票库存减少 import javautilCalendar; import javautilLocale; public class Seller extends Thread { private String windowName; private TicketManager ticketManager; public Seller(String windowName, TicketManager ticketManager) { thiswindowName = windowName; thisticketManager = ticketManager; } public void run() { int ticketNo = ticketManagerworkOff(); while (!interrupted() && ticketNo > 0) { Systemoutprintln(windowName + "售出票号" + ticketNo + ", at [ " + CalendargetInstance(LocaleCHINA) + " ]"); ticketNo = ticketManagerworkOff(); try { sleep(100L); } catch (InterruptedException ie) { ieprintStackTrace(); } } } } public class TicketManager { private int stock; private int remaind; private static TicketManager ticketManager; public static final TicketManager getInstance() { if (ticketManager == null) { ticketManager = new TicketManager(); } return ticketManager; } private TicketManager() { stock = 100; } public synchronized int workOff() { if (stock > 0) { return stock--; } return -1; } } public class Run { public static void main(String[] args) { TicketManager ticketManager = TicketManagergetInstance(); String[] windows = new String[] {"窗口一", "窗口二", "窗口三", "窗口四", "窗口五"}; Seller[] window = new Seller[windowslength]; for (int i = 0; i < windowslength; i++) { window[i] = new Seller(windows[i], ticketManager); window[i]start(); } } }

你把原来程序中直接读的地方,改成调用上面的函数,由该函数统一读行。这样,不管是你有 N 个线程,还是一个线程,都不会发生读的行重复,或者读的行不完整的现象了。

为了充分利用多线程读取,就需要把文件划分成多个区域,供每个线程读取。那么就需要有一个算法来计算出每个线程读取的开始位置和结束位置。那么首先根据配置的线程数和文件的总长度计,算出每个线程平均分配的读取长度。

但是有一点,由于文件是纯文本文件,必须按行来处理,如果分割点在某一行中间,那么这一行数据就会被分成两部分,分别由两个线程同时处理,这种情况是不能出现的。所以各个区域的结束点上的字符必须是换行符。第一个区域的开始位置是0,结束位置首先设为(文件长度/线程数),如果结束点位置不是换行符,就只能加1,直到是换行符位置。

如果多线程 *** 作,那么需要保证多个线程 *** 作同一个对象,此外请保证先有线程放进内容,其他线程才能拿出数据。

附上具体参考代码:

public class Test{

public static void main(String args[])throws Exception{

File file = new File("D:\\Testjava");//Text文件

BufferedReader br = new BufferedReader(new FileReader(file));//构造一个BufferedReader类来读取文件

String s = null;

while((s = brreadLine())!=null){//使用readLine方法,一次读一行

Systemoutprintln(s);

}

brclose();;

}

}

如果该方法不涉及写公共的资源比如一个静态的变量或者写文件,修改某个数据库的值的时候没有影响

比如你这个类里的方法只是对输入的参数做一个计算然后返回计算的值就没有影响。

但是如果是修改公共的资源比如修改数据库中存储的一个value则有可能出现问题,如:

public void writeDb(String key, String value) {

collectiondb();

write(key, value);

closeDbCollection();

}

因为Java的线程运行顺序是不一定的,可以第一个线程运行完连接数据库到后挂起了,这时候第二个线程开始运行,如果你的collectiondb()处理使用的是类中的一个实例变量Connection conn来保存数据库的连接,当第二个线程运行完毕以后conn也被关闭了,第一个线程继续执行write函数写数据库值的时候就会抛出异常。

这是一个例子,还有其他可能产生脏数据的问题

多线程如果使用公共资源的话最好在方法上声明synchronized关键字让其同步

以上就是关于多线程并发访问数据库中不同记录时应该采用什么办法全部的内容,包括:多线程并发访问数据库中不同记录时应该采用什么办法、java 多线程怎么读取一个表了的多个配置、java 多线程 访问数据问题等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/sjk/10187233.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-05-06
下一篇2023-05-06

发表评论

登录后才能评论

评论列表(0条)

    保存