尝试在浏览器的两个不同选项卡中打开以下页面。点击刷新按钮以避免从浏览器缓存中获取页面:
protected void Page_Load(object sender, EventArgs e)
{
Thread.Sleep(10000);
Response.Write(DateTime.Now.ToString());
}
Run Code Online (Sandbox Code Playgroud)
如您所见,似乎为每个请求创建了一个线程,并且它们没有相互等待,也没有获取锁。
现在创建以下页面,以及 GlobalCustomClass
全局自定义类
public class GlobalCustomClass
{
public static string GlobalVariable
{
get;
set;
}
}
Run Code Online (Sandbox Code Playgroud)
默认.aspx
protected void Page_Load(object sender, EventArgs e)
{
GlobalCustomClass.GlobalVariable = "Default page";
Thread.Sleep(10000);
Response.Write(DateTime.Now.ToString());
Response.Write("<br />");
Response.Write(GlobalCustomClass.GlobalVariable);
}
Run Code Online (Sandbox Code Playgroud)
页面2.aspx
protected void Page_Load(object sender, EventArgs e)
{
Response.Write(DateTime.Now.ToString());
Response.Write("<br />");
GlobalCustomClass.GlobalVariable = "Page2";
Response.Write(GlobalCustomClass.GlobalVariable);
}
Run Code Online (Sandbox Code Playgroud)
刷新默认页面,在 10 秒过去之前,刷新 Page2....Default.aspx 正在呈现“Page2”。是的,它不是线程安全的。
现在试试这个,在两个浏览器选项卡中打开以下页面:
protected void Page_Load(object sender, EventArgs e)
{
Session["x"] = "ABC"; …
Run Code Online (Sandbox Code Playgroud) architecture asp.net performance application-pool thread-safety
已经有类似的问题,但它没有回答以下问题。众所周知,字段的值不一定在线程之间立即同步。但是局部变量也是这种情况吗?可以抛出 IllegalStateException 吗?
public static void main(String[] args) {
final Thread mainThread = Thread.currentThread();
final Integer[] shared = new Integer[1];
new Thread(new Runnable() {
@Override
public void run() {
shared[0] = 1;
mainThread.interrupt();
}
}).start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
if (shared[0] == null) throw new IllegalStateException("Is this possible?");
}
}
Run Code Online (Sandbox Code Playgroud) 我有一个 Python 脚本,我也想在凌晨 3 点运行它。想简单地把这样的东西放在它的顶部。
while not 3am:
sleep(10)
Run Code Online (Sandbox Code Playgroud)
这样它会持续睡眠 10 秒钟,直到凌晨 3 点。在凌晨 3 点,它执行下面的其余代码,然后退出脚本。有没有一种简单的方法可以做到这一点?
我有一个共享向量,可通过两个线程访问。
线程A的函数推入向量,线程B的函数将向量完全交换以进行处理。
MovetoVec(PInfo* pInfo)
{
while(1)
{
if(GetSwitch())
{
swapBucket->push_back(pInfo);
toggles = true;
break;
}
else if(pInfo->tryMove == 5)
{
delete pInfo;
break;
}
pInfo->tryMove++;
Sleep(25);
}
}
Run Code Online (Sandbox Code Playgroud)
线程A试图使原子布尔值toggles
变为true并推入向量。(上面的MoveToVec
函数将被许多线程调用)。函数GetSwitch定义为
GetSwitch()
{
if(toggles)
{
toggles = false;
return TRUE;
}
else
return FALSE;
}
Run Code Online (Sandbox Code Playgroud)
toggles
这是atomic_bool,线程B中另一个交换向量的函数是
GetClassObj(vector<ProfiledInfo*>* toSwaps)
{
if(GetSwitch())
{
toSwaps->swap(*swapBucket);
toggles = true;
}
}
Run Code Online (Sandbox Code Playgroud)
如果GetSwitch返回false,则threadB不执行任何操作。在这里我不使用任何锁定。它在大多数情况下都有效。但是有时pInfo
,swapBucket 中的对象之一为NULL。我知道这是因为同步不良。
我遵循这种类型的GetSwitch()逻辑只是为了忽略由锁定引起的开销。我应该放弃这个并返回互斥或关键部分的东西吗?
如果我有以下2个for循环将在不同的线程上运行:
for (int ii = 1; ii < times.Length; ii+=2)
{
if (times[ii] - times[ii - 1] > maxGap)
return false;
}
for (int ii = 2; ii < times.Length; ii += 2)
{
if (times[ii] - times[ii - 1] > maxGap)
return false;
}
Run Code Online (Sandbox Code Playgroud)
这种情况可能发生在两个线程都试图从times
Array中的项读取的情况下,例如两个线程都可以同时尝试读取times[1]
.
鉴于这两个线程只会读取这些数组,这是一个问题,例如它是否会导致我的代码崩溃或任何其他意外的负面后果?
由于该类是一次性的,我以某种方式认为它可能应该用作单例。我应该如何安全地使用它?
// Code uses Nuget package FluentAssertions
var key = "supersecret";
var keybytes = Encoding.UTF8.GetBytes(key);
var hmac = new HMACSHA256(keybytes);
var tokenBytes = Encoding.UTF8.GetBytes("tokentocompute");
var expected = hmac.ComputeHash(tokenBytes);
await Task.WhenAll(
Enumerable.Range(0, 100).Select(i => Task.Run(() =>
{
var hash = hmac.ComputeHash(tokenBytes);
// This throws most of the time
hash.ShouldBeEquivalentTo(expected, $"{i}");
}))
);
Run Code Online (Sandbox Code Playgroud)
我不认为它是HMACSHA1.ComputeHash() 线程安全问题的重复,因为它专门讨论设置密钥的不同线程,而我在每次调用中都使用相同的密钥。重读之后,它可能仍然是重复的。坐等各位大佬的意见。
我正在处理下面的面试问题,我需要使用两个线程打印出字母和数字.一个打印字母(a,b,c ... z)和其他打印数字(1,2,3 ...... 26).现在我必须以这样的方式实现它,输出应该是:
a
1
b
2
...
...
z
26
Run Code Online (Sandbox Code Playgroud)
所以我想出了下面的代码一,没有同步,但由于某种原因它不打印最后一个字母表 z
class Output {
private static final int MAX = 26;
private static int count = 1;
private static final Queue<Character> queue = new LinkedList<>(Arrays.asList(new Character[] {
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r',
's', 't', 'u', 'v', 'w', 'x', 'y', 'z'}));
private boolean isAlphabet = true;
public void printAlphabet() {
while (true) {
if …
Run Code Online (Sandbox Code Playgroud) 我是Go的新手,我需要创建一个变量线程安全的。我知道在Java中您只能使用synchronized
关键字,但是似乎没有类似的东西存在。有什么方法可以同步变量?
我编写了以下通用缓存的实现,其中func
将提供值(计算,读取文件等).它是线程安全的吗?
#pragma once
#include "stdafx.h"
#include <map>
#include <functional>
#include <mutex>
using namespace std;
template<class T1, class T2>
class __declspec(dllexport) CacheOf
{
map<T1, T2> _cache;
function<T2(T1)> _func;
mutex CacheMtx;
public:
CacheOf(function<T2(T1)> func);
~CacheOf();
T2 Get(T1);
void Clear();
};
template <class T1, class T2>
CacheOf<T1, T2>::CacheOf(std::function<T2(T1)> func)
{
_func = func;
}
template <class T1, class T2>
CacheOf<T1, T2>::~CacheOf()
{
_cache.clear();
}
template <class T1, class T2>
auto CacheOf<T1, T2>::Get(T1 key) -> T2
{
auto it = _cache.find(key); …
Run Code Online (Sandbox Code Playgroud) 我对线程安全的方法参数的理解是:通过值传递到方法中的参数作为方法调用的参数中给出的数据的副本传递,因此它们对于该方法调用是唯一的,不能由任何其他任务更改。相反,参考参数可能会因在其他任务中运行的代码而易于更改。
话虽如此,我仍然不太清楚为什么下面的代码(不制作循环计数器的本地副本)在每个线程中返回相同的数字。
static void ExampleFunc(int i) =>
Console.WriteLine("task " + i);
Run Code Online (Sandbox Code Playgroud)
for (int i = 0; i < 10; i++)
{
int taskN = i; //local copy instead of i
Task.Run(() => Func(i));
}
Run Code Online (Sandbox Code Playgroud)
实际输出是:任务10十次,
我通过传递taskN而不是i来获得正确的输出(任务1到10)。
由于传递了类型值参数,因此我期望得到相同的结果。
thread-safety ×10
c# ×3
c++ ×2
concurrency ×2
java ×2
architecture ×1
arrays ×1
asp.net ×1
c++17 ×1
go ×1
mutex ×1
performance ×1
python ×1
sleep ×1
templates ×1
vector ×1