使用共享资源创建多个线程

阿尔沃·鲍恩(Arvo Bowen)

好的,所以我在创建一堆线程并且它们都使用同一对象时遇到了问题。我的想法是我有一个项目的“队列”(又名列表),并且应该逐个处理这些项目,直到所有项目都已处理完毕。当前,这在一个线程上工作得很好(当我更改threadcount = 1时),但是当我尝试将其设置为threadcount = 2且线程竞争时,这一切都变成了一个糟糕的地方。

这是我制作的一些快速课程,以详细说明我要完成的工作...我有很好的预感,这与使用“ lock”关键字有关,但我不是100 %知道如何使用。

在您的答案中,请提供一个解决方案代码示例,以使您的答案清晰明了。谢谢!

代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
using System.Diagnostics;

namespace MyNamespace
{
    class Class1
    {
        static void Main()
        {
            Debug.WriteLine("starting application...");

            int threadcount = 2;
            List<Task> tasks = new List<Task>();

            List<Class2> myObjs = new List<Class2>();
            myObjs.Add(new Class2("list item 1"));
            myObjs.Add(new Class2("list item 2"));
            myObjs.Add(new Class2("list item 3"));
            myObjs.Add(new Class2("list item 4"));
            myObjs.Add(new Class2("list item 5"));
            myObjs.Add(new Class2("list item 6"));
            myObjs.Add(new Class2("list item 7"));
            myObjs.Add(new Class2("list item 8"));
            myObjs.Add(new Class2("list item 9"));

            Debug.WriteLine("about to create " + threadcount + " task(s)...");

            int t = 0;
            do
            {
                t++;
                Debug.WriteLine("creating task " + t);
                Class3 starter = new Class3();
                tasks.Add(starter.StartNewThread(myObjs));
            } while (t < threadcount);

            Task.WaitAll(tasks.ToArray());
            Debug.WriteLine("all tasks have completed");
        }
    }

    class Class2
    {
        private string m_status;
        public string status
        {
            get { return m_status; }
            set { m_status = value; }
        }

        private string m_text;
        public string text
        {
            get { return m_text; }
            set { m_text = value; }
        }

        private int m_threadid;
        public int threadid
        {
            get { return m_threadid; }
            set { m_threadid = value; }
        }

        public Class2()
        {
            m_status = "created";
            m_text = "";
            m_threadid = 0;
        }
        public Class2(string intext)
        {
            m_status = "created";
            m_text = intext;
            m_threadid = 0;
        }
    }

    class Class3
    {
        public Task StartNewThread(List<Class2> taskObjs)
        {
            Task<List<Class2>> task = Task.Factory
                .StartNew(() => threadTaskWorker(taskObjs),
                CancellationToken.None,
                TaskCreationOptions.None,
                TaskScheduler.Default)
                .ContinueWith(completed_task => threadTaskComplete(completed_task.Result));

            return task;
        }
        private List<Class2> threadTaskWorker(List<Class2> taskObjs)
        {
            Thread.CurrentThread.Name = "thread" + Thread.CurrentThread.ManagedThreadId;
            Debug.WriteLine("thread #" + Thread.CurrentThread.ManagedThreadId + " created.");

            //Process all items in the list that need processing
            Class2 nextObj;
            do
            {
                //Look for next item in list that needs processing
                nextObj = null;
                foreach (Class2 taskObj in taskObjs)
                {
                    if (taskObj.status == "created")
                    {
                        nextObj = taskObj;
                        break;
                    }
                }

                if (nextObj != null)
                {
                    Debug.WriteLine("thread #" + Thread.CurrentThread.ManagedThreadId +
                        " is handling " + nextObj.text);

                    nextObj.status = "processing";
                    nextObj.threadid = Thread.CurrentThread.ManagedThreadId;
                    nextObj.text += "(handled)";

                    Random rnd = new Random();
                    Thread.Sleep(rnd.Next(300, 3000));

                    nextObj.status = "completed";
                }
            } while (nextObj != null);

            Debug.WriteLine("thread #" + Thread.CurrentThread.ManagedThreadId + " destroyed.");

            //Return the task object
            return taskObjs;
        }
        private List<Class2> threadTaskComplete(List<Class2> taskObjs)
        {
            Debug.WriteLine("a thread has finished, here are the current item's status...");

            foreach (Class2 taskObj in taskObjs)
            {
                Debug.WriteLine(taskObj.text +
                    " thread:" + taskObj.threadid +
                    " status:" + taskObj.status);
            }

            //Return the task object
            return taskObjs;
        }
    }
}

结果:

/*
starting application...
about to create 2 task(s)...
creating task 1
creating task 2
thread #10 created.
thread #11 created.
thread #10 is handling list item 1
thread #11 is handling list item 1
thread #10 is handling list item 2
thread #11 is handling list item 2
thread #10 is handling list item 3
thread #11 is handling list item 4
thread #10 is handling list item 5
thread #11 is handling list item 5
thread #10 is handling list item 6
thread #11 is handling list item 6
thread #10 is handling list item 7
thread #11 is handling list item 8
thread #10 is handling list item 9
thread #11 destroyed.
a thread has finished, here are the current item's status...
list item 1(handled) thread:11 status:completed
list item 2(handled)(handled) thread:11 status:completed
list item 3(handled) thread:10 status:completed
list item 4(handled) thread:11 status:completed
list item 5(handled)(handled) thread:11 status:completed
list item 6(handled)(handled) thread:11 status:completed
list item 7(handled) thread:10 status:completed
list item 8(handled) thread:11 status:completed
list item 9(handled) thread:10 status:processing
thread #10 destroyed.
a thread has finished, here are the current item's status...
list item 1(handled) thread:11 status:completed
list item 2(handled)(handled) thread:11 status:completed
list item 3(handled) thread:10 status:completed
list item 4(handled) thread:11 status:completed
list item 5(handled)(handled) thread:11 status:completed
list item 6(handled)(handled) thread:11 status:completed
list item 7(handled) thread:10 status:completed
list item 8(handled) thread:11 status:completed
list item 9(handled) thread:10 status:completed
all tasks have completed
*/

预期结果:

/*
starting application...
about to create 2 task(s)...
creating task 1
creating task 2
thread #10 created.
thread #11 created.
thread #10 is handling list item 1
thread #11 is handling list item 2
thread #10 is handling list item 3
thread #11 is handling list item 4
thread #10 is handling list item 5
thread #10 is handling list item 6
thread #11 is handling list item 7
thread #10 is handling list item 8
thread #11 is handling list item 9
thread #10 destroyed.
a thread has finished, here are the current item's status...
list item 1(handled) thread:10 status:completed
list item 2(handled) thread:11 status:completed
list item 3(handled) thread:10 status:completed
list item 4(handled) thread:11 status:completed
list item 5(handled) thread:10 status:completed
list item 6(handled) thread:10 status:completed
list item 7(handled) thread:11 status:completed
list item 8(handled) thread:10 status:completed
list item 9(handled) thread:11 status:processing
thread #11 destroyed.
a thread has finished, here are the current item's status...
list item 1(handled) thread:10 status:completed
list item 2(handled) thread:11 status:completed
list item 3(handled) thread:10 status:completed
list item 4(handled) thread:11 status:completed
list item 5(handled) thread:10 status:completed
list item 6(handled) thread:10 status:completed
list item 7(handled) thread:11 status:completed
list item 8(handled) thread:10 status:completed
list item 9(handled) thread:11 status:completed
all tasks have completed
*/
阿尔沃·鲍恩(Arvo Bowen)

首先,感谢@khargoosh和@interceptwind的输入!这是帮助我了解锁并提出此解决方案的关键。这就是我想出的,最终效果很好!它已经过测试,结果为ACTUAL结果。在答案中,我决定使用4个线程来显示结果。

代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
using System.Diagnostics;

namespace MyNamespace
{
    class Class1
    {
        static void Main()
        {
            Debug.WriteLine("starting application...");

            int threadcount = 4;
            List<Task> tasks = new List<Task>();

            List<Class2> myObjs = new List<Class2>();
            myObjs.Add(new Class2("list item 1"));
            myObjs.Add(new Class2("list item 2"));
            myObjs.Add(new Class2("list item 3"));
            myObjs.Add(new Class2("list item 4"));
            myObjs.Add(new Class2("list item 5"));
            myObjs.Add(new Class2("list item 6"));
            myObjs.Add(new Class2("list item 7"));
            myObjs.Add(new Class2("list item 8"));
            myObjs.Add(new Class2("list item 9"));

            Debug.WriteLine("about to create " + threadcount + " task(s)...");

            int t = 0;
            do
            {
                t++;
                Debug.WriteLine("creating task " + t);
                Class3 starter = new Class3();
                tasks.Add(starter.StartNewThread(myObjs));
            } while (t < threadcount);

            Task.WaitAll(tasks.ToArray());
            Debug.WriteLine("all tasks have completed");
        }
    }

    class Class2
    {
        private object m_locker = new object();
        public object locker
        {
            get { return m_locker; }
            set { m_locker = value; }
        }

        private string m_status;
        public string status
        {
            get { return m_status; }
            set { m_status = value; }
        }

        private string m_text;
        public string text
        {
            get { return m_text; }
            set { m_text = value; }
        }

        private int m_threadid;
        public int threadid
        {
            get { return m_threadid; }
            set { m_threadid = value; }
        }

        public Class2()
        {
            m_status = "created";
            m_text = "";
            m_threadid = 0;
        }
        public Class2(string intext)
        {
            m_status = "created";
            m_text = intext;
            m_threadid = 0;
        }
    }

    class Class3
    {
        public Task StartNewThread(List<Class2> taskObjs)
        {
            Task<List<Class2>> task = Task.Factory
                .StartNew(() => threadTaskWorker(taskObjs),
                CancellationToken.None,
                TaskCreationOptions.None,
                TaskScheduler.Default)
                .ContinueWith(completed_task => threadTaskComplete(completed_task.Result));

            return task;
        }
        private List<Class2> threadTaskWorker(List<Class2> taskObjs)
        {
            Thread.CurrentThread.Name = "thread" + Thread.CurrentThread.ManagedThreadId;
            Debug.WriteLine("thread #" + Thread.CurrentThread.ManagedThreadId + " created.");

            //Process all items in the list that need processing
            Class2 nextObj;
            do
            {
                //Look for next item in list that needs processing
                nextObj = null;
                foreach (Class2 taskObj in taskObjs)
                {
                    nextObj = taskObj;

                    lock (nextObj.locker)
                    {
                        if (taskObj.status == "created")
                        {
                            nextObj.status = "processing";
                            break;
                        }
                        else nextObj = null;
                    }
                }

                if (nextObj != null)
                {
                    Debug.WriteLine("thread #" + Thread.CurrentThread.ManagedThreadId +
                        " is handling " + nextObj.text);

                    nextObj.threadid = Thread.CurrentThread.ManagedThreadId;
                    nextObj.text += "(handled)";

                    Random rnd = new Random();
                    Thread.Sleep(rnd.Next(300, 3000));

                    nextObj.status = "completed";
                }
            } while (nextObj != null);

            Debug.WriteLine("thread #" + Thread.CurrentThread.ManagedThreadId + " destroyed.");

            //Return the task object
            return taskObjs;
        }
        private List<Class2> threadTaskComplete(List<Class2> taskObjs)
        {
            Debug.WriteLine("a thread has finished, here are the current item's status...");

            foreach (Class2 taskObj in taskObjs)
            {
                Debug.WriteLine(taskObj.text +
                    " thread:" + taskObj.threadid +
                    " status:" + taskObj.status);
            }

            //Return the task object
            return taskObjs;
        }
    }
}

结果:

/*
starting application...
about to create 4 task(s)...
creating task 1
creating task 2
creating task 3
creating task 4
thread #11 created.
thread #13 created.
thread #12 created.
thread #12 is handling list item 3
thread #11 is handling list item 1
thread #13 is handling list item 2
thread #14 created.
thread #14 is handling list item 4
thread #12 is handling list item 5
thread #11 is handling list item 6
thread #13 is handling list item 7
thread #14 is handling list item 8
thread #12 is handling list item 9
thread #11 destroyed.
a thread has finished, here are the current item's status...
list item 1(handled) thread:11 status:completed
list item 2(handled) thread:13 status:completed
list item 3(handled) thread:12 status:completed
list item 4(handled) thread:14 status:completed
list item 5(handled) thread:12 status:completed
list item 6(handled) thread:11 status:completed
list item 7(handled) thread:13 status:processing
list item 8(handled) thread:14 status:processing
list item 9(handled) thread:12 status:processing
thread #13 destroyed.
thread #14 destroyed.
a thread has finished, here are the current item's status...
list item 1(handled) thread:11 status:completed
list item 2(handled) thread:13 status:completed
list item 3(handled) thread:12 status:completed
a thread has finished, here are the current item's status...
list item 1(handled) thread:11 status:completed
list item 4(handled) thread:14 status:completed
list item 5(handled) thread:12 status:completed
list item 2(handled) thread:13 status:completed
list item 3(handled) thread:12 status:completed
list item 6(handled) thread:11 status:completed
list item 7(handled) thread:13 status:completed
list item 4(handled) thread:14 status:completed
list item 5(handled) thread:12 status:completed
list item 8(handled) thread:14 status:completed
list item 9(handled) thread:12 status:processing
list item 6(handled) thread:11 status:completed
list item 7(handled) thread:13 status:completed
list item 8(handled) thread:14 status:completed
list item 9(handled) thread:12 status:processing
thread #12 destroyed.
a thread has finished, here are the current item's status...
list item 1(handled) thread:11 status:completed
list item 2(handled) thread:13 status:completed
list item 3(handled) thread:12 status:completed
list item 4(handled) thread:14 status:completed
list item 5(handled) thread:12 status:completed
list item 6(handled) thread:11 status:completed
list item 7(handled) thread:13 status:completed
list item 8(handled) thread:14 status:completed
list item 9(handled) thread:12 status:completed
all tasks have completed
*/

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

Java:将创建对象的访问权限授予共享资源

来自分类Dev

在项目之间共享资源

来自分类Dev

WebGL共享资源Web Worker

来自分类Dev

修改同步方法后,所有Java线程都会看到共享资源更新吗?

来自分类Dev

修改同步方法后,所有Java线程都会看到共享资源更新吗?

来自分类Dev

WinRT在Universal App中使用共享资源xaml文件

来自分类Dev

如何与多个线程共享资源(串行端口)

来自分类Dev

Docker如何共享资源

来自分类Dev

使用逻辑编程使用共享资源安排任务

来自分类Dev

对象的共享资源

来自分类Dev

函数式编程中的共享资源

来自分类Dev

Apache Beam:在实例中的所有线程之间共享资源

来自分类Dev

在线程之间共享资源(文件,互斥体)

来自分类Dev

单例类的方法是否是线程安全的,方法内部是否使用了共享资源?

来自分类Dev

优化对共享资源的访问同步

来自分类Dev

如何在共享资源作为参数的for循环中使用std future和async与线程异步处理?

来自分类Dev

在多线程程序中更新共享资源

来自分类Dev

在1个解决方案中的多个项目之间共享资源。Visual Studio 2010

来自分类Dev

具有共享资源的多线程服务器

来自分类Dev

TFS多个构建定义之间共享资源

来自分类Dev

将线程同步责任转移到共享资源中

来自分类Dev

跨部门的Project Server共享资源

来自分类Dev

使用Gradle在多个Eclipse WTP项目之间共享资源

来自分类Dev

函数式编程中的共享资源

来自分类Dev

用单例和多线程实现共享资源算法

来自分类Dev

线程:共享资源特殊情况

来自分类Dev

Azure:跨多个资源组共享资源

来自分类Dev

了解多线程共享资源:shmid、shmat、shmdt

来自分类Dev

在 Huey 中使用线程管理共享资源

Related 相关文章

  1. 1

    Java:将创建对象的访问权限授予共享资源

  2. 2

    在项目之间共享资源

  3. 3

    WebGL共享资源Web Worker

  4. 4

    修改同步方法后,所有Java线程都会看到共享资源更新吗?

  5. 5

    修改同步方法后,所有Java线程都会看到共享资源更新吗?

  6. 6

    WinRT在Universal App中使用共享资源xaml文件

  7. 7

    如何与多个线程共享资源(串行端口)

  8. 8

    Docker如何共享资源

  9. 9

    使用逻辑编程使用共享资源安排任务

  10. 10

    对象的共享资源

  11. 11

    函数式编程中的共享资源

  12. 12

    Apache Beam:在实例中的所有线程之间共享资源

  13. 13

    在线程之间共享资源(文件,互斥体)

  14. 14

    单例类的方法是否是线程安全的,方法内部是否使用了共享资源?

  15. 15

    优化对共享资源的访问同步

  16. 16

    如何在共享资源作为参数的for循环中使用std future和async与线程异步处理?

  17. 17

    在多线程程序中更新共享资源

  18. 18

    在1个解决方案中的多个项目之间共享资源。Visual Studio 2010

  19. 19

    具有共享资源的多线程服务器

  20. 20

    TFS多个构建定义之间共享资源

  21. 21

    将线程同步责任转移到共享资源中

  22. 22

    跨部门的Project Server共享资源

  23. 23

    使用Gradle在多个Eclipse WTP项目之间共享资源

  24. 24

    函数式编程中的共享资源

  25. 25

    用单例和多线程实现共享资源算法

  26. 26

    线程:共享资源特殊情况

  27. 27

    Azure:跨多个资源组共享资源

  28. 28

    了解多线程共享资源:shmid、shmat、shmdt

  29. 29

    在 Huey 中使用线程管理共享资源

热门标签

归档