多线程

概述

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

多任务处理: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. html5 filereader 读取图片信息

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  2. views中class定义(类的写法)CBV

    from django.views import View class Home(View): def dispatch(self, request, *args, **kwargs): print( ...

  3. 对avalon的类名操作进行升级

    在对SVG元素进行类名操作时,发现有一个坑爹的事情,它的className竟然是一个对象,因此报一系列BUG.第一次想到的方法是添加setClasses, getClasses两个更底层的方法.于是相 ...

  4. Symfony 从路由认识它

    经过上一篇文章之后,我们呢,可以访问这个默认的页面,你也会看到一堆高级的debug工具.好了,这次我们开始更多地了解这个symfony2.0. 首先我们要明白一点,Symfony2 的配置是一个着实很 ...

  5. HBase实验(CRUD和MR入库)

    目录 前期准备 在HBase shell中实现CRUD操作 1. 启动命令行客户端 2. 创建表 3. 删除.新增列族 4. 删除表teacher 5. 新增数据 6. 查看数据 用Java API实 ...

  6. hack vba password, en useful...

    Unbelivibale, but I found a very simple way that really works! Do the follwoing: 1. Create a new sim ...

  7. YourKit Java Profiler安装和破解

    YourKit Java Profiler是业界领先的Java性能剖析工具.其独立版本安装成功且首次启动 YourKit Java Profiler 后,会弹出一个对话框,让用户选择 YourKit ...

  8. Redis 安装配制

    Redis 安装配制 redis 安装分为单机安装.伪集群安装.集群安装. Redis 下载地址:http://www.redis.cn/download.html Redis 在线测试工具:http ...

  9. Disruptor 系列(一)快速入门

    Disruptor 系列(一)快速入门 Disruptor:是一个开源的并发框架,能够在 无锁 的情况下实现网络的 Queue 并发操作,所以处理数据的能力比 Java 本身提供的并发类容器要大的多, ...

  10. HTML5 本地存储+layer弹层组件制作记事本

    什么是 HTML5 Web 存储? 使用HTML5可以在本地存储用户的浏览数据. 早些时候,本地存储使用的是 cookie.但是Web 存储需要更加的安全与快速. 这些数据不会被保存在服务器上,但是这 ...