多线程

概述

单任务处理:一个任务完成后才能进行下一个任务。

多任务处理:CPU分时操作,每个任务看似同时运行。

进程

应用程序的一个运行实例,包含程序所需资源的内存区域,是操作系统进行资源分配的单元,进程隔离了正在执行的不同程序。(打开某一个软件,分配CPU,隔离其他软件)

优点:进程间相互独立,互不影响。

线程

进程中的一个执行单元(进程是程序边界,要靠线程执行程序,线程指向方法,执行完毕释放线程),是CPU分配时间片的单位,一个进程可以包含多个线程,且相互独立,共享当前进程所有资源。

优点:

  1. 并发执行,合理使用CPU资源。
  2. 相同程序的线程共享堆内存。

缺点:

  1. 频繁创建/销毁线程增加性能开销。
  2. 访问共享资源可能造成冲突。
  3. 辅助线程不能访问Unity API。

注意事项:

  1. Unity的API不能在辅助线程运行。
  2. Unity定义的基本结构(int,Vector3,Quaternion等)可以在辅助线程计算。
  3. Unity定义的基本类型的函数可以在分线程运行。

多线程

在单核系统的一个单位时间内,CPU只能运行单个线程,运行顺序取决于线程的优先级。如果在单位时间内线程未能完成执行,系统就会把线程的状态信息保存到线程的本地存储器(TLS) 中,以便下次执行时恢复执行。因为切换频密,所以多线程可被视作同时运行,而实际只是一个假象。

在多核系统的一个单位时间内,进程或线程可以在不同的CPU中运行,使得真正的并行处理。

适用性

耗时的任务,通过多线程可以并行处理。

一个程序完成多个任务,通过多个线程使用多核CPU来处理,可以提升性能。

线程实现

命名空间:System.Threading;

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Threading; public class ThreadDemo1 : MonoBehaviour
{
private Thread thread;
private void Start01()
{
//Func1();//同步调用 一次性完成0 1 2 3 4 .... //线程调用
//thread = new Thread(Fun1);
//thread.Start();
//睡眠一秒 期间没有CPU调度 0 睡眠一秒,依次循环 1 2 3 4... //thread = new Thread(Fun2);
//thread.Start(5);
//方法重载 参数object类型 thread = new Thread(Fun4);
thread.Start(); //ThreadPool.QueueUserWorkItem(Fun3,null);
//线程池开辟的线程无法设置前后台/优先级等
//通过线程池开辟线程 不能Start启用
}
//thread.Start() //无参
private void Fun1()
{
for (int i = ; i < ; i++)
{
signal.WaitOne();
//整数 代表最长的等待时间
Thread.Sleep();
print(i);
}
}
////thread.Start(5) //有参
private void Fun2(object o)
{
int count = (int)o;
for (int i = ; i < count; i++)
{
Thread.Sleep();
print(i);
}
}
/// <summary>
/// 对象池
/// </summary>
private void Fun3(object o)
{
//int[] arr = (int[])o;
//int count = (int)o;
for (int i = ; i < ; i++)
{
Thread.Sleep();//模拟此时操作一分钟
print(i);//主线程 卡 指的就是生命周期 }
} /// <summary>
/// 死循环 怎么办
/// </summary>
private void Fun4()
{
int n = ;
while (true)
{
Thread.Sleep();
print(++n);
}
}
/// <summary>
/// 退出线程
/// </summary>
private void OnApplicationQuit()
{
//thread.Abort();
//结束线程
//主线程卡顿的情况 可以开辟新的线程
}
/// <summary>
/// 信号灯
/// </summary>
private ManualResetEvent signal; private void Start()
{
//信号灯 绿灯行 红灯停
signal = new ManualResetEvent(true);
//true表示绿灯 false 表示红灯
thread = new Thread(Fun1);
thread.Start();
}
private void OnGUI()
{
if (GUILayout.Button("线程暂停"))
{
signal.Reset();
}
if (GUILayout.Button("线程继续"))
{
signal.Set();
}
}
}

Thread 

  1. 创建线程: 创建Thread类的一个对象,分配一个线程工作方法 。

Thread thread = new Thread(工作方法);

  1. 启动线程:Start方法。

thread.Start();

  1. 终止线程:工作方法自然退出、线程终止。

thread. Abort ();

ThreadPool

在频繁创建和销毁线程时使用线程池技术,可以有效减少时间以及系统资源的开销。

ThreadPool.QueueUserWorkItem(工作方法);

/后台线程

前台线程:程序必须等待所有前台线程结束后才能退出。(只要有一个前台线程未退出,进程就不会终止!即说的就是程序不会关闭!)[Thread创建的线程默认前台线程]

后台线程:程序不考虑后台线程,后台线程随程序退出而结束。[ThreadPool创建的线程默认后台线程]

备注:Unity程序退出后,前台线程也随即关闭。

新建的子线程可以是前台线程或者后台线程,前台线程必须全部执行完,即使主线程关闭掉,这时进程仍然存活。

线程状态

未启动状态 Unstarted:创建线程对象。

运行状态Running:执行绑定的方法。

等待睡眠阻塞状态 WaitSleepJoin:暂时停止执行,资源交给其他线程使用。

终止状态 Stopped:线程销毁。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using UnityEngine.UI;
using System.Threading; public class ThreadDemo : MonoBehaviour
{
private int second = ;
private Text text;
private void Start()
{
text = GetComponent<Text>();
Thread thread = new Thread(Timer);
thread.Start();
}
private void Update()
{
if (action!=null)
{
action();
action = null;
}
}
private void Timer()
{
while (second>)
{
Thread.Sleep();//睡一会 期间没有CPU的调度 action = () =>
{
second--;
text.text = string.Format("{0:d2}:{1:d2}", second / , second % );
};
}
}
private Action action;
}

线程同步

需要同步的原因:

多个线程同一时刻访问共享资源(线程共享实例变量,静态变量),由于每个线程都不知道其他线程的操作,结果将产生不可预知的数据损坏。

同步:

线程之间相互等待排队执行。

如何同步:

将需要同步的代码用关键字lock锁定,锁定后该代码对于线程来讲就是独占使用的。当其他线程试图进入被锁定的临界区时,只能等待解锁后才可访问。因此锁定代码时是排队访问的,所以叫线程同步。

 

Lock锁原理:

对象在堆中的分配:实例成员、同步块索引 (默认索引-1)、类型指针(指向类型对象)。

对象上锁后,同步索引块会指向同步块数组中的一个对象。

当其他对象执行lock的时候会等待该对象同步索引设置为-1。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Threading; public class Bank
{
public static int Money = ;
public static object o = new object();
//必须使用引用类型
//优先使用object
public static void Get(int val)
{
lock (o)//-1 0 只有是-1的时候 锁打开 否则锁关闭
{ //同步块索引 类型对象指针
//共享读 独占写
//枷锁(对象) 流程
if (Money >= val)
{
//线程冲突 0 -1 -2 如何解决???加锁
Thread.Sleep();
Money -= val;
Debug.Log("取钱成功!余额:" + Money);
}
else
{
Debug.Log("取钱失败!余额:" + Money);
}
//线程离开代码块 索引块 设置为-1
}
}
} public class ThreadDemo2 : MonoBehaviour
{
private void Start()
{
//Bank.Get(1); //同步调用 排队
ThreadPool.QueueUserWorkItem(o =>
{
Bank.Get();
});
////线程调用(多线程) 不排队
}
}

[多线程] Thread的更多相关文章

  1. c#中@标志的作用 C#通过序列化实现深表复制 细说并发编程-TPL 大数据量下DataTable To List效率对比 【转载】C#工具类:实现文件操作File的工具类 异步多线程 Async .net 多线程 Thread ThreadPool Task .Net 反射学习

    c#中@标志的作用   参考微软官方文档-特殊字符@,地址 https://docs.microsoft.com/zh-cn/dotnet/csharp/language-reference/toke ...

  2. 2.匿名类,匿名类对象,private/protected/public关键字、abstract抽象类,抽象方法、final关键字的使用,多线程Thread类start方法原理

    package com.bawei.multithread; //注意:模板方法我们通常使用抽象类或者抽象方法!这里我们为了方便在本类中使用就没有使用抽象类/抽象方法 public class Tem ...

  3. 多线程-Thread和ThreadPool

    多线程原理 多线程都是基于委托的. 多线程优缺点 缺点: 1.导致程序复杂,开发调试维护困难,特别是线程交互. 2.线程过多导致服务器卡死,因为占用CPU 内存等资源. 优点: 1.良好的交互,特别对 ...

  4. Java多线程Thread

    转自:http://www.cnblogs.com/lwbqqyumidi/p/3804883.html Java总结篇系列:Java多线程(一)   多线程作为Java中很重要的一个知识点,在此还是 ...

  5. java 多线程--- Thread Runnable Executors

    java 实现多线程的整理: Thread实现多线程的两种方式: (1)继承 Thread类,同时重载 run 方法: class PrimeThread extends Thread { long ...

  6. python进阶学习笔记(四)--多线程thread

    在使用多线程之前,我们首页要理解什么是进程和线程. 什么是进程? 计算机程序只不过是磁盘中可执行的,二进制(或其它类型)的数据.它们只有在被读取到内存中,被操作系统调用的时候才开始它们的生命期.进程( ...

  7. php多线程thread开发与应用的例子

    Php多线程的使用,首先需要PHP5.3以上版本,并安装pthreads PHP扩展,可以使PHP真正的支持多线程,扩展如何安装请自行百度 PHP扩展下载:https://github.com/kra ...

  8. 多线程(Thread),其实很简单!

    目录:  1:线程简介 2:怎么操作线程      3:Thread的常用方法 4:简单的获奖机     5:应用程序域   线程:是Windows任务调度的最小单位.线程是程序中的一个执行流,每个线 ...

  9. 【C#多线程】C#多线程 Thread 开发基础

    引用 using System; using System.Threading; 多线程代码 Thread mainthread = new Thread(ExecuteThread); mainth ...

  10. android 多线程Thread,Runnable,Handler,AsyncTask

    先看两个链接: 1.http://www.2cto.com/kf/201404/290494.html 2. 链接1: android 的多线程实际上就是java的多线程.android的UI线程又称 ...

随机推荐

  1. 数据结构和算法之栈和队列三:自定义一个栈包含min函数

    我们都知道一个栈的特点是后进先出,如果我们要实现在O(1)的时间内找到一个栈里面的最小值,我们应该怎么解决?如果我们采用遍历获取的思路那必然所需要的时间是O(N)与我们所需要的要求明显不符合,这时候我 ...

  2. Java的bitmap到C

    在很多情况下android程序员需用到c,bimap这个是一个java中的类,android底层有一个skbitmap类和其对应.先在我遇到了需要把java的bitmap传递到底层中进行一些操作.现在 ...

  3. 迷你MVVM框架 avalonjs 1.2.4发布

    这段时间一直忙于建立avalon的单元测试,与重构官网.对avalon的更新都是来自公司内部的需求,性能优化与一些BUG修复. 添加大量调试日志. 重构shimController,以提高性能. cr ...

  4. css继承和层叠

    在前面介绍了如何利用文档结构和css选择器为元素应用各种丰富的样式,今天来好好聊聊css的层叠和继承,先说说概念. 继承:一个元素向其后代元素传递属性值所采用的机制,说的通俗点,就是元素的某些属性可以 ...

  5. flume 配置说明

    Flume中的HDFS Sink应该是非常常用的,其中的配置参数也比较多,在这里记录备忘一下. channel type hdfs path 写入hdfs的路径,需要包含文件系统标识,比如:hdfs: ...

  6. jquey下eq()的使用注意事项

    写在开始的话: 今天在公司路经同事工位,发现在写jquery代码,刚好遇见一个bug,于是驻足看了一会,发现了jq遍历方法中eq()的使用的一个容易犯错的地方. 同事的代码大概意思是这样的: < ...

  7. Web页面显示日期和动态时刻脚本

    <script language="JavaScript" type="text/JavaScript">    <!--        tm ...

  8. mybatis框架入门程序:演示通过mybatis实现数据库的删除操作

    1.mybatis的基本配置工作可以在我的这篇博客中查看:https://www.cnblogs.com/wyhluckdog/p/10149480.html 2.删除用户的映射文件: <!-- ...

  9. Template7学习记录

    来源:http://idangero.us/template7/#.V2iXqJGF6Ul 测试用json数据: var jsonData = { people: [ { firstName: 'Jo ...

  10. C语言中的undefined behavior

    参考: http://www.cnblogs.com/aoaoblogs/archive/2010/08/31/1813982.html