3 线程进程安全
- 格式:ppt
- 大小:799.50 KB
- 文档页数:49


编程思想之多线程与多进程(2)——线程优先级与线程安全
线程优先级
现在主流操作系统(如Windows、Linux、Mac OS X)的任务调度除了具有前面提到的时间片轮转的特点外,还有优先级调度(Priority Schedule)的特点。优先级调度决定了线程按照什么顺序轮流执行,在具有优先级调度的系统中,线程拥有各自的线程优先级(Thread Priority)。具有高优先级的线程会更早地执行,而低优先级的线程通常要等没有更高优先级的可执行线程时才会被执行。
线程的优先级可以由用户手动设置,此外系统也会根据不同情形调整优先级。通常情况下,频繁地进入等待状态(进入等待状态会放弃之前仍可占用的时间份额)的线程(如IO线程),比频繁进行大量计算以至于每次都把所有时间片全部用尽的线程更受操作系统的欢迎。因为频繁进入等待的线程只会占用很少的时间,这样操作系统可以处理更多的任务。我们把频繁等待的线程称之为IO密集型线程(IO Bound Thread),而把很少等待的线程称之为CPU密集型线程(CPU Bound Thread)。IO密集型线程总是比CPU密集型线程更容易得到优先级的提升。
线程饿死:
在优先级调度下,容易出现一种线程饿死的现象。一个线程饿死是说它的优先级较低,在它执行之前总是有比它优先级更高的线程等待执行,因此这个低优先级的线程始终得不到执行。当CPU密集型的线程优先级较高时,其它低优先级的线程就很可能出现饿死的情况;当IO密集型线程优先级较高时,其它线程相对不容易造成饿死的善,因为IO线程有大量的等待时间。为了避免线程饿死,调度系统通常会逐步提升那些等待了很久而得不到执行的线程的优先级。这样,一个线程只要它等待了足够长的时间,其优先级总会被提升到可以让它执行的程度,也就是说这种情况下线程始终会得到执行,只是时间的问题。
在优先级调度环境下,线程优先级的改变有三种方式:
1. 用户指定优先级;
- 1 - 保证线程安全的方式
线程安全是指多个线程访问同一个对象时,不会出现不可预期的结果,保证程序的正确性。下面介绍一些保证线程安全的方式。
1. 使用synchronized关键字
synchronized关键字可以保证同一时刻只有一个线程访问某个对象,其他线程需要等待。使用synchronized关键字可以保证线程安全,但会影响程序的性能。
2. 使用Lock接口
Lock接口提供了比synchronized更加灵活的锁机制,可以实现更复杂的线程同步。使用Lock接口可以提高程序的性能,但需要手动释放锁,容易出现死锁。
3. 使用线程安全的数据结构
Java提供了许多线程安全的数据结构,如ConcurrentHashMap和ConcurrentLinkedQueue等。使用这些数据结构可以避免出现线程安全问题。
4. 使用volatile关键字
volatile关键字用于保证变量的可见性,即对一个volatile变量的修改对其他线程立即可见。使用volatile关键字可以避免出现由于缓存导致的线程安全问题。
5. 线程间通信
线程间通信是指多个线程之间传递信息或者控制权。Java提供了许多线程间通信的方式,如wait/notify、CountDownLatch和 - 2 - CyclicBarrier等。使用这些方式可以保证线程安全。
综上所述,保证线程安全的方式有很多,具体选择哪种方式需要根据实际情况来决定。同时,需要注意锁的释放、死锁等问题,避免出现线程安全问题。
Python中的线程安全
概述
线程安全是指多线程程序中,多个线程同时操作一个共享资源时,不会出现数据竞争和内存泄漏等问题的能力。Python作为一种高级语言,被广泛应用于各种领域。在多线程编程方面,Python提供了许多线程安全的模块和方法,使得程序员能够方便地编写线程安全的代码。本文将介绍Python中线程安全的概念、问题和解决方案。
线程安全的概念
线程安全是指在多线程环境下,多个线程在同时访问和修改同一个共享资源时,不会出现数据竞争、死锁、内存泄漏、数据一致性等问题。具体来说,线程安全包含以下三个方面:
1.互斥性:当一个线程正在修改共享资源时,其他线程必须等待这个线程完成修改后才能继续访问共享资源。
2.可见性:当一个线程修改共享资源时,其他线程应该能够立即看到这个修改。 3.原子性:当一个线程修改多个共享资源时,这些修改应该被视为一个操作,要么全部成功,要么全部失败。
线程安全的问题
线程安全涉及到多线程并发访问共享资源的问题,主要包括以下几种:
1.数据竞争:当多个线程同时访问和修改同一个共享资源时,可能会导致数据竞争问题,即出现意料之外的结果。
2.死锁:当多个线程在等待共享资源时,出现循环等待的情况,导致所有线程都无法继续执行,这就是死锁。
3.内存泄漏:当多个线程同时分配和释放内存时,可能会出现内存泄漏问题,即已经分配的内存空间不能释放。
4.数据一致性:当多个线程同时访问和修改同一个共享资源时,可能会导致数据一致性问题,即不同线程访问到的共享资源值不同。
线程安全的解决方案
Python提供了许多线程安全的模块和方法,帮助程序员编写线程安全的代码,主要包括以下几种: 1.锁机制:Python中提供了多种锁机制,例如threading.Lock()、threading.RLock()等,可以确保同一时刻只有一个线程能够访问和修改共享资源。
2.原子操作:Python中提供了一些原子操作,例如threading.Event()、threading.Condition()等,可以确保多个共享资源的修改是原子性的,要么全部成功,要么全部失败。
线程不安全与线程安全⽰例
线程不安全与线程安全 ⽰例代码:
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Incorrect counter");
var c = new Counter();
var t1 = new Thread(() => TestCounter(c));
var t2 = new Thread(() => TestCounter(c));
var t3 = new Thread(() => TestCounter(c));
t1.Start();
t2.Start();
t3.Start();
t1.Join();
t2.Join();
t3.Join();
Console.WriteLine("Total count: {0}",c.Count);
Console.WriteLine("--------------------------");
Console.WriteLine("Correct counter");
var c1 = new CounterWithLock();
t1 = new Thread(() => TestCounter(c1));
t2 = new Thread(() => TestCounter(c1));
t3 = new Thread(() => TestCounter(c1));
t1.Start();
t2.Start();
t3.Start();
t1.Join();
t2.Join();
t3.Join();
Console.WriteLine("Total count: {0}", c1.Count);
Console.ReadKey();
}
static void TestCounter(CounterBase c)
{
for (int i = 0; i < 100000; i++)