好友
阅读权限25
听众
最后登录1970-1-1
|
25吾爱币
本帖最后由 Cool_Breeze 于 2021-3-20 18:03 编辑
源代码:
[C#] 纯文本查看 复制代码 using System;
using System.Threading;
using System.Collections;
using System.Collections.Concurrent;
class Multimedia
{
static Args[] argsArr =
{
new Args(),
new Args(),
new Args(),
new Args(),
};
public static void Main()
{
// 创建线程池
Thread[] th = new Thread[4];
for (int i=0; i<th.Length; i++)
{
th[i] = new Thread(Multimedia.getNumber);
th[i].Name = i.ToString();
th[i].Start(argsArr[i]);
}
// 向队列发送信息
for (int i=0; i<20; i++)
{
Args.queue.Enqueue(i);
}
// 等待线程结束
int flag = 0;
while (true)
{
foreach (var n in th)
{
if (n.ThreadState == ThreadState.Stopped) flag++;
else
{
flag = 0;break;
}
}
if (flag == th.Length) break;
}
// Thread.Sleep(2000);
foreach (var n in argsArr)
Console.WriteLine(n.GetCount()); // 最后结果 40 正确
Console.ReadKey();
}
class Args
{
public static readonly ConcurrentQueue<int> queue = new ConcurrentQueue<int>(); // 只会创建一次
private static object Lock = new object();
private static int Count = 0;
// private static readonly int[] extra = {1,2,3,4,5,6,7,8,9,10};
public static readonly object extraLock = new object();
// private static int extraIdex = 0;
private readonly int[] extra = {1,2,3,4,5}; // 主线程信息发送完成,在发送这个信息
private int extraIdex = 0;
public void Add()
{
lock(Lock)
{
Count++;
Console.WriteLine("++++++++++++++++++++++++++++++++++++{0}",Count);
}
}
public int GetCount()
{
return Count;
}
// public int GetExtraAdd()
// {
// lock(extraLock) // 访问已经锁了
// {
// if (extraIdex >= extra.Length) return -1; // 使线程结束
// else return extra[extraIdex++];
// }
// }
public int GetExtraAdd() // 返回 extra 一个元素
{
int temp = 0;
lock (extraLock)
{
if (extraIdex >= extra.Length) return -1; // 使线程结束
temp = extra[extraIdex];
extraIdex++;
return temp;
}
}
}
static void getNumber(object argsEx)
{
Args args = argsEx as Args;
int temp = 0;
while (true)
{
// 调用这条语句,最后结果就会受影响
// Console.WriteLine("当前线程名:{0} 当前 Count:{1}", Thread.CurrentThread.Name, temp);
try
{
Monitor.Enter(Args.queue);
lock(Args.queue) // 只有保证这四个线程锁的是同一个引用对象就行
{
if (Args.queue.TryDequeue(out temp) == false)
{
Args.queue.Enqueue(args.GetExtraAdd()); // 额外添加一点数据
continue;
}
if (temp == -1) break; // 线程结束
}
args.Add(); // 成功获取值以后Args.Count ++;
}
// catch
// {
// lock(Args.extraLock)
// {
// Args.queue.Enqueue(args.GetExtraAdd()); // 额外添加一点数据
// }
// }
finally
{
Monitor.Exit(Args.queue);
}
}
Console.WriteLine("{0} 已经退出", Thread.CurrentThread.Name);
}
}
输出正确结果为:
++++++++++++++++++++++++++++++++++++1
++++++++++++++++++++++++++++++++++++2
++++++++++++++++++++++++++++++++++++3
++++++++++++++++++++++++++++++++++++4
++++++++++++++++++++++++++++++++++++5
0 已经退出
++++++++++++++++++++++++++++++++++++6
++++++++++++++++++++++++++++++++++++7
++++++++++++++++++++++++++++++++++++8
++++++++++++++++++++++++++++++++++++9
++++++++++++++++++++++++++++++++++++10
1 已经退出
++++++++++++++++++++++++++++++++++++11
++++++++++++++++++++++++++++++++++++12
++++++++++++++++++++++++++++++++++++13
++++++++++++++++++++++++++++++++++++14
++++++++++++++++++++++++++++++++++++15
2 已经退出
++++++++++++++++++++++++++++++++++++16
++++++++++++++++++++++++++++++++++++17
++++++++++++++++++++++++++++++++++++18
++++++++++++++++++++++++++++++++++++19
++++++++++++++++++++++++++++++++++++20
++++++++++++++++++++++++++++++++++++21
++++++++++++++++++++++++++++++++++++22
++++++++++++++++++++++++++++++++++++23
++++++++++++++++++++++++++++++++++++24
++++++++++++++++++++++++++++++++++++25
++++++++++++++++++++++++++++++++++++26
++++++++++++++++++++++++++++++++++++27
++++++++++++++++++++++++++++++++++++28
++++++++++++++++++++++++++++++++++++29
++++++++++++++++++++++++++++++++++++30
++++++++++++++++++++++++++++++++++++31
++++++++++++++++++++++++++++++++++++32
++++++++++++++++++++++++++++++++++++33
++++++++++++++++++++++++++++++++++++34
++++++++++++++++++++++++++++++++++++35
++++++++++++++++++++++++++++++++++++36
++++++++++++++++++++++++++++++++++++37
++++++++++++++++++++++++++++++++++++38
++++++++++++++++++++++++++++++++++++39
++++++++++++++++++++++++++++++++++++40
3 已经退出
40
40
40
40
调用 107行 这一行语句就会出现结果不对!!!
// 调用这条语句,最后结果就会受影响
// Console.WriteLine("当前线程名:{0} 当前 Count:{1}", Thread.CurrentThread.Name, temp);
错误结果小于 40 (这个结果会变动,不固定,有时候又是正确的)
错误输出:
当前线程名:0 当前 Count:0
当前线程名:1 当前 Count:0
当前线程名:0 当前 Count:0
++++++++++++++++++++++++++++++++++++1
当前线程名:1 当前 Count:1
++++++++++++++++++++++++++++++++++++2
当前线程名:1 当前 Count:2
当前线程名:1 当前 Count:0
++++++++++++++++++++++++++++++++++++3
当前线程名:1 当前 Count:1
++++++++++++++++++++++++++++++++++++4
当前线程名:1 当前 Count:0
++++++++++++++++++++++++++++++++++++5
当前线程名:1 当前 Count:1
++++++++++++++++++++++++++++++++++++6
当前线程名:1 当前 Count:2
++++++++++++++++++++++++++++++++++++7
当前线程名:1 当前 Count:3
++++++++++++++++++++++++++++++++++++8
当前线程名:1 当前 Count:4
++++++++++++++++++++++++++++++++++++9
当前线程名:1 当前 Count:5
++++++++++++++++++++++++++++++++++++10
当前线程名:1 当前 Count:6
++++++++++++++++++++++++++++++++++++11
当前线程名:1 当前 Count:7
++++++++++++++++++++++++++++++++++++12
当前线程名:1 当前 Count:8
++++++++++++++++++++++++++++++++++++13
当前线程名:1 当前 Count:9
++++++++++++++++++++++++++++++++++++14
当前线程名:1 当前 Count:10
++++++++++++++++++++++++++++++++++++15
当前线程名:1 当前 Count:11
++++++++++++++++++++++++++++++++++++16
当前线程名:1 当前 Count:12
++++++++++++++++++++++++++++++++++++17
当前线程名:1 当前 Count:13
++++++++++++++++++++++++++++++++++++18
当前线程名:1 当前 Count:14
++++++++++++++++++++++++++++++++++++19
当前线程名:0 当前 Count:0
当前线程名:3 当前 Count:0
当前线程名:1 当前 Count:15
当前线程名:2 当前 Count:0
++++++++++++++++++++++++++++++++++++20
当前线程名:0 当前 Count:16
++++++++++++++++++++++++++++++++++++21
当前线程名:3 当前 Count:17
++++++++++++++++++++++++++++++++++++22
当前线程名:1 当前 Count:18
++++++++++++++++++++++++++++++++++++23
当前线程名:2 当前 Count:19
++++++++++++++++++++++++++++++++++++24
当前线程名:2 当前 Count:3
++++++++++++++++++++++++++++++++++++25
当前线程名:2 当前 Count:1
当前线程名:2 当前 Count:0
++++++++++++++++++++++++++++++++++++26
当前线程名:2 当前 Count:1
当前线程名:2 当前 Count:0
++++++++++++++++++++++++++++++++++++27
当前线程名:2 当前 Count:2
当前线程名:2 当前 Count:0
当前线程名:0 当前 Count:0
当前线程名:3 当前 Count:0
++++++++++++++++++++++++++++++++++++28
当前线程名:2 当前 Count:3
当前线程名:2 当前 Count:0
++++++++++++++++++++++++++++++++++++29
当前线程名:2 当前 Count:4
++++++++++++++++++++++++++++++++++++30
当前线程名:2 当前 Count:4
当前线程名:2 当前 Count:0
++++++++++++++++++++++++++++++++++++31
当前线程名:2 当前 Count:5
当前线程名:2 当前 Count:0
当前线程名:0 当前 Count:0
当前线程名:1 当前 Count:0
3 已经退出
++++++++++++++++++++++++++++++++++++32
当前线程名:2 当前 Count:2
当前线程名:1 当前 Count:0
++++++++++++++++++++++++++++++++++++33
当前线程名:2 当前 Count:3
当前线程名:2 当前 Count:0
2 已经退出
当前线程名:0 当前 Count:0
++++++++++++++++++++++++++++++++++++34
当前线程名:1 当前 Count:5
1 已经退出
当前线程名:0 当前 Count:0
当前线程名:0 当前 Count:0
0 已经退出
34
34
34
34 |
最佳答案
查看完整内容
你想要正确结果,好像是同步的吧,你代码逻辑有问题
免费评分
-
查看全部评分
|
发帖前要善用【论坛搜索】功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。 |
|
|
|
|