竞争条件的定义:竞争条件或竞赛危险是系统或过程中的缺陷,其中过程的输出或结果出乎意料地且严重地依赖于其他事件的顺序或时间.
考虑以下伪代码:
Global variable i initialized to 6;
Thread 1:
acquire(lock l)
increment global variable i, i.e. i++;
Thread 2:
acquire(lock l)
double the value of global var i, i.e.: i*=2;
Run Code Online (Sandbox Code Playgroud)
如果T1首先获得锁定l并且T2获得T2秒,则i的值将为14.另一方面,如果T2首先获得锁定l并且T1获得第二锁定,则i的值将是13.
那么,这是不是竞争条件?
更新:经过多次评论和回答后,意见仍然存在分歧.我的观点是"是的,这是竞争条件"类别.实际上我把这个例子作为竞争条件情况,在另一个问题上.与此同时,我还在"不,这不是竞争条件"类别中阅读了一些有趣的评论.我想我会解决并得出结论认为这是一种竞争条件,取决于观察问题的视角/水平.但是,我还在等待有趣的答案/评论.
假设我有一个对象,多个线程可以读取/写入state和someValue变量.如果这些变量是int,double,enums等类型,我是否需要添加锁定?
enum State: String {
case one
case two
}
class Object {
var state: State
var someValue: Double
}
Run Code Online (Sandbox Code Playgroud) 我有一个网页,我想跟踪没有使用数据库访问它的次数.
我考虑过XML,每次用户访问页面时都会更新文件:
<?xml version='1.0' encoding='utf-8'?>
<counter>8</counter>
Run Code Online (Sandbox Code Playgroud)
然后我认为在一个单独的文件中声明一个PHP计数器然后每次用户访问该页面时更新它都是一个更好的主意.
counter.php
<?php
$counter = 0;
?>
Run Code Online (Sandbox Code Playgroud)
update_counter.php:
<?php
include "counter.php";
$counter += 1;
$var = "<?php\n\t\$counter = $counter;\n?>";
file_put_contents('counter.php', $var);
?>
Run Code Online (Sandbox Code Playgroud)
这样,每次update_counter.php访问时,counter.php文件中的变量都会增加.
无论如何,我注意到如果counter.php文件有$counter = 5,并且update_counter.php文件被同时访问的1000个用户访问,则文件同时被读取1000次(因此5在所有请求中读取该值)counter.php文件将被更新有价值5+1 (=6)而不是1005.
有没有办法让它在不使用数据库的情况下工作?
我将尝试在JPA事务隔离级别中描述我的问题.
数据库结构:
Table1 - >将PK定义为日期('ddMMyyyy')Table2 - >用FK到Table1JPA(隔离级别::)read_commited- 代码:
Query query = em.createQuery("from Table1 trd where trd.id = :d");
query.setParameter("d", date);
Table1 t = null;
try{
t = (Table1) query.getSingleResult();
}catch(javax.persistence.NoResultException e){
t = null;
}
if(t==null){
t=new Table1 (date);
em.persist(trd);
}
for(Table2 q:tables2){
q.setTable1(t);
em.merge(q);
}
Run Code Online (Sandbox Code Playgroud)
因此,过程检查db中是否存在记录,如果不存在则创建新记录.如果系统只基于一个线程,则方法完全是核心.否则可能会出现这样的情况:
他们俩都认为这样的记录尚不存在,所以加上新记录.在提交交易之前,一切都很好.第一个将被提交,没有任何例外,购买与主键复制相关的第二个上升异常.
除了改变隔离级别之外,是否有可能保留这种情况SERIALIZABLE?
任何人都可以向我解释什么是竞争条件,如何避免它,以及如何在 Java 代码中找到它?
好吧,我几天才知道“竞争条件”,我有两个例子,也许它们不够好,这就是为什么我需要你的帮助:)希望你们中的任何人都可以为我解释。
示例1:检查然后采取行动:
if(vector.contains(e))//check
{
vector.remove(e)
}
Run Code Online (Sandbox Code Playgroud)
如果有2个线程可以访问,线程1在检查向量包含e后挂起,e在向量中,然后线程2访问检查然后从向量中删除e,然后线程1回来做删除动作,会发生错误,因为e是已被 thread2 删除。
示例2:读取修改写入:
假设我们在一个方法中有一个计数器变量,一旦方法被调用,计数器增加1,
counter++
Run Code Online (Sandbox Code Playgroud)
这不是原子操作,它有 3 个步骤: 1. 获取值 2. 增加值 3. 分配给值
我对比赛条件的了解都在这里,希望您能与我分享您的知识:)
谢谢
我试图找出 psycopg2 连接池之间的SimpleConnectionPool区别ThreadedConnectionPool。
该文档说:
SimpleConnectionPool连接只能在单线程应用程序/脚本内使用。
ThreadedConnectionPool连接可以在多线程应用程序/脚本中安全地使用。
这里是什么safely意思?
我的理解/困惑:
"""
eg1: Simple Connection Pooling example
"""
from psycopg2.pool
from concurrent.futures
def someTask(id):
# CRUD queries to Postgres, that I will be multithreading
print(f"Thread: {id}")
conn = simple_pool.getconn()
# do DB operation
simple_pool = psycopg2.pool.SimpleConnectionPool(10, 15, #DB Info)
with concurrent.futures.ThreadPoolExecutor(max_workers=10) as executor:
executor.map(someTask, range(1,10))
Run Code Online (Sandbox Code Playgroud)
"""
eg2: Threaded Connection Pooling example
"""
from psycopg2.pool
from concurrent.futures
def someTask(id):
# CRUD queries to …Run Code Online (Sandbox Code Playgroud) 如果我有两个线程和一个全局变量(一个线程不断循环读取该变量;另一个线程不断循环写入该变量),那会不会发生什么事情呢?(例如:异常,错误)。如果是这样,请采取什么措施来防止这种情况发生。我正在阅读有关互斥锁的知识,它们允许互斥访问一个线程的变量。这是否意味着只有该线程可以读写该线程,而没有其他线程可以读写?
我最近被问到这个问题。我正在研究ARM架构,并且尝试过研究它,但我觉得我没有得到正确的答案。
我的想法是,关键原因是为了避免干扰正在进行的中断,我们使用设置启用寄存器来启用所有中断,使用清除启用寄存器来禁用所有中断。
这是正确的理由吗?这背后是否有更深层次的解释?有一些文件解释这个设计决策吗?
编辑:抱歉,我正在使用的芯片是 Cortex M4
以下代码是线程安全的吗?
public object DemoObject {get;set;}
public void DemoMethod()
{
if (DemoObject is IDemoInterface demo)
{
demo.DoSomething();
}
}
Run Code Online (Sandbox Code Playgroud)
如果其他线程在处理时修改DemoObject(例如设置为空)DemoMethod,是否保证在if块内局部变量demo总是被正确分配(给类型的实例IDemoInterface)?
我正在学习多线程。谁能说出为什么即使有两个线程以100为增量,输出总是100?
public class App {
public static int counter = 0;
public static void process() {
Thread thread1 = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 100; ++i) {
++counter;
}
}
});
Thread thread2 = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 100; ++i) {
++counter;
}
}
});
thread1.start();
thread2.start();
}
public static void main(String[] args) {
process();
System.out.println(counter);
} …Run Code Online (Sandbox Code Playgroud)