[多线程] Thread
多线程
概述
单任务处理:一个任务完成后才能进行下一个任务。
多任务处理:CPU分时操作,每个任务看似同时运行。
进程
应用程序的一个运行实例,包含程序所需资源的内存区域,是操作系统进行资源分配的单元,进程隔离了正在执行的不同程序。(打开某一个软件,分配CPU,隔离其他软件)
优点:进程间相互独立,互不影响。
线程
进程中的一个执行单元(进程是程序边界,要靠线程执行程序,线程指向方法,执行完毕释放线程),是CPU分配时间片的单位,一个进程可以包含多个线程,且相互独立,共享当前进程所有资源。
优点:
- 并发执行,合理使用CPU资源。
- 相同程序的线程共享堆内存。
缺点:
- 频繁创建/销毁线程增加性能开销。
- 访问共享资源可能造成冲突。
- 辅助线程不能访问Unity API。
注意事项:
- Unity的API不能在辅助线程运行。
- Unity定义的基本结构(int,Vector3,Quaternion等)可以在辅助线程计算。
- 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
- 创建线程: 创建Thread类的一个对象,分配一个线程工作方法 。
Thread thread = new Thread(工作方法);
- 启动线程:Start方法。
thread.Start();
- 终止线程:工作方法自然退出、线程终止。
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的更多相关文章
- 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.匿名类,匿名类对象,private/protected/public关键字、abstract抽象类,抽象方法、final关键字的使用,多线程Thread类start方法原理
package com.bawei.multithread; //注意:模板方法我们通常使用抽象类或者抽象方法!这里我们为了方便在本类中使用就没有使用抽象类/抽象方法 public class Tem ...
- 多线程-Thread和ThreadPool
多线程原理 多线程都是基于委托的. 多线程优缺点 缺点: 1.导致程序复杂,开发调试维护困难,特别是线程交互. 2.线程过多导致服务器卡死,因为占用CPU 内存等资源. 优点: 1.良好的交互,特别对 ...
- Java多线程Thread
转自:http://www.cnblogs.com/lwbqqyumidi/p/3804883.html Java总结篇系列:Java多线程(一) 多线程作为Java中很重要的一个知识点,在此还是 ...
- java 多线程--- Thread Runnable Executors
java 实现多线程的整理: Thread实现多线程的两种方式: (1)继承 Thread类,同时重载 run 方法: class PrimeThread extends Thread { long ...
- python进阶学习笔记(四)--多线程thread
在使用多线程之前,我们首页要理解什么是进程和线程. 什么是进程? 计算机程序只不过是磁盘中可执行的,二进制(或其它类型)的数据.它们只有在被读取到内存中,被操作系统调用的时候才开始它们的生命期.进程( ...
- php多线程thread开发与应用的例子
Php多线程的使用,首先需要PHP5.3以上版本,并安装pthreads PHP扩展,可以使PHP真正的支持多线程,扩展如何安装请自行百度 PHP扩展下载:https://github.com/kra ...
- 多线程(Thread),其实很简单!
目录: 1:线程简介 2:怎么操作线程 3:Thread的常用方法 4:简单的获奖机 5:应用程序域 线程:是Windows任务调度的最小单位.线程是程序中的一个执行流,每个线 ...
- 【C#多线程】C#多线程 Thread 开发基础
引用 using System; using System.Threading; 多线程代码 Thread mainthread = new Thread(ExecuteThread); mainth ...
- android 多线程Thread,Runnable,Handler,AsyncTask
先看两个链接: 1.http://www.2cto.com/kf/201404/290494.html 2. 链接1: android 的多线程实际上就是java的多线程.android的UI线程又称 ...
随机推荐
- html5 filereader 读取图片信息
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- views中class定义(类的写法)CBV
from django.views import View class Home(View): def dispatch(self, request, *args, **kwargs): print( ...
- 对avalon的类名操作进行升级
在对SVG元素进行类名操作时,发现有一个坑爹的事情,它的className竟然是一个对象,因此报一系列BUG.第一次想到的方法是添加setClasses, getClasses两个更底层的方法.于是相 ...
- Symfony 从路由认识它
经过上一篇文章之后,我们呢,可以访问这个默认的页面,你也会看到一堆高级的debug工具.好了,这次我们开始更多地了解这个symfony2.0. 首先我们要明白一点,Symfony2 的配置是一个着实很 ...
- HBase实验(CRUD和MR入库)
目录 前期准备 在HBase shell中实现CRUD操作 1. 启动命令行客户端 2. 创建表 3. 删除.新增列族 4. 删除表teacher 5. 新增数据 6. 查看数据 用Java API实 ...
- hack vba password, en useful...
Unbelivibale, but I found a very simple way that really works! Do the follwoing: 1. Create a new sim ...
- YourKit Java Profiler安装和破解
YourKit Java Profiler是业界领先的Java性能剖析工具.其独立版本安装成功且首次启动 YourKit Java Profiler 后,会弹出一个对话框,让用户选择 YourKit ...
- Redis 安装配制
Redis 安装配制 redis 安装分为单机安装.伪集群安装.集群安装. Redis 下载地址:http://www.redis.cn/download.html Redis 在线测试工具:http ...
- Disruptor 系列(一)快速入门
Disruptor 系列(一)快速入门 Disruptor:是一个开源的并发框架,能够在 无锁 的情况下实现网络的 Queue 并发操作,所以处理数据的能力比 Java 本身提供的并发类容器要大的多, ...
- HTML5 本地存储+layer弹层组件制作记事本
什么是 HTML5 Web 存储? 使用HTML5可以在本地存储用户的浏览数据. 早些时候,本地存储使用的是 cookie.但是Web 存储需要更加的安全与快速. 这些数据不会被保存在服务器上,但是这 ...