---
title: "Unity Jobsystem问题"
author: "石心.Yong"
published_by: "Perrin Yong"
canonical: https://www.pystone.net/notes/uwa-answer-unity-job-system-issue/
type: note
content_role: source
source_type: "source"
visibility: public
id_stability: rename-stable
source_path: "10-计算机、信息技术与工程/05-游戏图形与运行时/我的UWA问答/2021-03-10 - Unity Jobsystem问题.md"
content_hash: 51f11ea21ae37816b6370ceff77f00523ca4d2a80384687f466149933c32106d
knowledge_version: 224c990773de.5fa8af6e39fa
site_commit: 224c990773de166d23a886306577dd90379529ce
notes_commit: 5fa8af6e39fa3891d1b9b4832bfa6c4e0ecaaf0a
---
# Unity Jobsystem问题

> **note · 我的 UWA 问答**
> 本文收录我在 UWA 问答发表的公开回答。问题内容归原提问者；回答保留当时语境，技术结论可能受 Unity 版本、平台和项目条件限制。

## 问题

```
using CSharp;

using Unity.Burst;

using Unity.Collections.LowLevel.Unsafe;

using UnityEngine;

using UnityEngine.Jobs;

using Unity.Collections;

using Unity.Jobs;

public class JobTest : MonoBehaviour

{

    // Start is called before the first frame update

    public Transform t1;

    public Transform t2;

    public TransformAccessArray TransformAccessArray;

    void Start()

    {

        TransformAccessArray = new TransformAccessArray(50000,64);

    }

    private JobHandle handle;

    // Update is called once per frame

    void Update()

    {

        if (!handle.IsCompleted)

        {

            return;

        }

        if (TransformAccessArray.length == 0)

        {

            TransformAccessArray.Add(t1);

            TransformAccessArray.Add(t2);

        }

        float t = Time.time;

        Debug.Log("time:" + t);

        NativeList<int> end_list = new NativeList<int>(TransformAccessArray.length,Allocator.TempJob);

        NativeList<int> end_id_list = new NativeList<int>(TransformAccessArray.length,Allocator.TempJob);

        UpdateJob job = new UpdateJob

        {

            time = t,

            end_list = end_list,

            end_id_list = end_id_list,

        };

        handle = job.Schedule(TransformAccessArray);

        handle.Complete();

        if (end_id_list.Length != end_list.Length)

        {

            Debug.LogError("error time:" + t);

        }

        else

        {

            Debug.LogWarning("right time:" + t);

        }

        end_list.Dispose();

        end_id_list.Dispose();

    }

}

using System;

using Unity.Burst;

using Unity.Collections;

using Unity.Collections.LowLevel.Unsafe;

using UnityEngine;

using UnityEngine.Jobs;

namespace CSharp

{

    [BurstCompile]

    public struct UpdateJob : IJobParallelForTransform

    {

        [NativeDisableContainerSafetyRestriction] public NativeList<int> end_list;

        [NativeDisableContainerSafetyRestriction] public NativeList<int> end_id_list;

        [ReadOnly] public float time;

        public void Execute(int index, TransformAccess transform)

        {

            end_list.Add(index);

            end_id_list.Add(index);

            int a = end_list.Length;

            int b = end_id_list.Length;

        }

    }

}
```

执行多线程之后发现，end*id*list.Length和 end_list.Length的长度有时候不一样，谁能解答一下

- 提问者：hardy
- 提问时间：2021-03-09 22:55:15

## 我的回答

这样写的话，两个线程是并行的，并且是线程不安全的：

![image.png](/media/34bd632fd9984a66727b.png)

两个线程对指令的执行的先后顺序是不确定的。

如果两个线程依次对end*list进行Add的话，end*list就会加入两个元素。

如果两个线程同时取得end_list，同时进行Add，就会产生错误——两个线程都执行完后，某个List只添加了一个元素。

可以用如下方法进行验证：

![image.png](/media/c04f2a57817b2a4bc354.png)

![image.png](/media/cde75dfd8dd35816d13b.png)

如果对数据的访问进行加锁，保证一个线程访问list时，另外一个线程无法访问，就不会出现题主所述的问题。**不过这多线程执行就没有意义了，相当于顺序执行。**

- 回答时间：2021-03-10 02:06:15
- 最后更新：2021-03-10 02:07:28
- 采纳状态：未采纳

## 来源与关系

- 上位集合：[我的 UWA 问答](https://www.pystone.net/notes/my-uwa-answers/)
- UWA 标签：C#编程
- 原始问题：[Unity Jobsystem问题](https://answer.uwa4d.com/question/60471bd3cfa35d5b536699e8)
- 源页最后更新：2021-03-10 02:06:15
