多线程的实现方法

第一题:线程的基本概念、线程的基本状态及状态之间的关系?

概念:线程是进程中执行运算的最小单位,是进程中的一个实体,是被系统独立调度和分派的基本单位,线程自己不拥有系统资源,只拥有一点在运行中必不可少的资源,但它可与同属一个进程的其它线程共享进程所拥有的全部资源。一个线程可以创建和撤消另一个线程,同一进程中的多个线程之间可以并发执行。

好处 :

(1)易于调度。

(2)提高并发性。通过线程可方便有效地实现并发性。进程可创建多个线程来执行同一程序的不同部分。

(3)开销少。创建线程比创建进程要快,所需开销很少。。

(4)利于充分发挥多处理器的功能。通过创建多线程进程,每个线程在一个处理器上运行,从而实现应用程序的并发性,使每个处理器都得到充分运行。

状态:运行、阻塞、挂起阻塞、就绪、挂起就绪

wait():使一个线程处于等待状态,并且释放所持有的对象的lock。

  sleep():使一个正在运行的线程处于睡眠状态,是一个静态方法, * 调用此方法要捕捉InterruptedException异常 * 。

  notify():唤醒一个处于等待状态的线程,注意的是在调用此方法的时候,并不能确切的唤醒某一个等待状态的线程 ,而是由JVM确定唤醒哪个线程,而且不是按优先级  。 

  Allnotity():唤醒所有处入等待状态的线程,注意并不是给所有唤醒线程一个对象的锁,而是让它们竞争。

状态之间的转换:准备就绪的进程,被CPU调度执行,变成运行态;

运行中的进程,进行I/O请求或者不能得到所请求的资源,变成阻塞态;

运行中的进程,进程执行完毕(或时间片已到),变成就绪态;

将阻塞态的进程挂起,变成挂起阻塞态,当导致进程阻塞的I/O操作在用户重启进程前完成(称之为唤醒),挂起阻塞态变成挂起就绪态,当用户在I/O操作结束之前重启进程,挂起阻塞态变成阻塞态;

将就绪(或运行)中的进程挂起,变成挂起就绪态,当该进程恢复之后,挂起就绪态变成就绪态;

第二题:线程与进程的区别?

这个题目问到的概率相当大,计算机专业考研中也常常考到。要想全部答出比较难。

进程和线程的关系:

(1)一个线程只能属于一个进程,而一个进程可以有多个线程,但至少有一个线程。

(2)资源分配给进程,同一进程的所有线程共享该进程的所有资源。

(3)处理机分给线程,即真正在处理机上运行的是线程。

(4)线程在执行过程中,需要协作同步。不同进程的线程间要利用消息通信的办法实现同步。线程是指进程内的一个执行单元,也是进程内的可调度实体.

进程与线程的区别:

(1)调度:线程作为调度和分配的基本单位,进程作为拥有资源的基本单位

(2)并发性:不仅进程之间可以并发执行,同一个进程的多个线程之间也可并发执行

(3)拥有资源:进程是拥有资源的一个独立单位,线程不拥有系统资源,但可以访问隶属于进程的资源.

(4)系统开销:在创建或撤消进程时,由于系统都要为之分配和回收资源,导致系统的开销明显大于创建或撤消线程时的开销。

第三题:多线程有几种实现方法,都是什么?

C++中多线程实现方法:

windows下通过api CreateThread,linux下则常用pthread库,这些都是最底层的实现,最新的C++11标准里增加了std::thread多线程库,使用第三方库的话就更多了,比如boost的thread等等,不推荐使用vc自家的_beginthread,尤其有跨平台需求的时候。

JAVA中实现多线程的方法:

1. 继承 Thread 类
    2. 实现 Runnable 接口再 new Thread(YourRunnableOjbect) 推荐

第四题:多线程同步和互斥有几种实现方法,都是什么?

线程间的同步方法大体可分为两类:用户模式和内核模式。顾名思义,内核模式就是指利用系统内核对象的单一性来进行同步,使用时需要切换内核态与用户态,而用户模式就是不需要切换到内核态,只在用户态完成操作。
用户模式下的方法有:原子操作(例如一个单一的全局变量),临界区。内核模式下的方法有:事件,信号量,互斥量。

第五题:多线程同步和互斥有何异同,在什么情况下分别使用他们?举例说明。

当有多个线程的时候,经常需要去同步这些线程以访问同一个数据或资源。例如,假设有一个程序,其中一个线程用于把文件读到内存,而另一个线程用于统计文件中的字符数。当然,在把整个文件调入内存之前,统计它的计数是没有意义的。但是,由于每个操作都有自己的线程,操作系统会把两个线程当作是互不相干的任务分别执行,这样就可能在没有把整个文件装入内存时统计字数。为解决此问题,你必须使两个线程同步工作。

所谓同步,是指散步在不同进程之间的若干程序片断,它们的运行必须严格按照规定的某种先后次序来运行,这种先后次序依赖于要完成的特定的任务。如果用对资源的访问来定义的话,同步是指在互斥的基础上(大多数情况),通过其它机制实现访问者对资源的有序访问。在大多数情况下,同步已经实现了互斥,特别是所有写入资源的情况必定是互斥的。少数情况是指可以允许多个访问者同时访问资源。

所谓互斥,是指散布在不同进程之间的若干程序片断,当某个进程运行其中一个程序片段时,其它进程就不能运行它们之中的任一程序片段,只能等到该进程运行完这个程序片段后才可以运行。如果用对资源的访问来定义的话,互斥某一资源同时只允许一个访问者对其进行访问,具有唯一性和排它性。但互斥无法限制访问者对资源的访问顺序,即访问是无序的。

第六题:进程间通信的方式?

(1)管道(pipe)及有名管道(named pipe):管道可用于具有亲缘关系的父子进程间的通信,有名管道除了具有管道所具有的功能外,它还允许无亲缘关系进程间的通信。

(2)信号(signal):信号是在软件层次上对中断机制的一种模拟,它是比较复杂的通信方式,用于通知进程有某事件发生,一个进程收到一个信号与处理器收到一个中断请求效果上可以说是一致的。

(3)消息队列(message queue):消息队列是消息的链接表,它克服了上两种通信方式中信号量有限的缺点,具有写权限得进程可以按照一定得规则向消息队列中添加新信息;对消息队列有读权限得进程则可以从消息队列中读取信息。

(4)共享内存(shared memory):可以说这是最有用的进程间通信方式。它使得多个进程可以访问同一块内存空间,不同进程可以及时看到对方进程中对共享内存中数据得更新。这种方式需要依靠某种同步操作,如互斥锁和信号量等。

(5)信号量(semaphore):主要作为进程之间及同一种进程的不同线程之间得同步和互斥手段。

(6)套接字(socket):这是一种更为一般得进程间通信机制,它可用于网络中不同机器之间的进程间通信,应用非常广泛。

以下多线程对int型变量x的操作,哪几个不需要进行同步:

A.x=y;      B. x++;    C.++x;    D. x=1;

答案参见:http://blog.csdn.net/jjj19891128/article/details/24392229

多线程中栈与堆是公有的还是私有的

一般来说栈是私有的

堆是共有的

但是你可以为特定的线程创建私有的堆

堆和栈的区别如下:

堆很灵活,但是不安全。对于对象,我们要动态地创建、销毁,不能说后创建的对象没有销毁,先前创建的对象就不能销毁,那样的话我们的程序就寸步难行,所以Java中用堆来存储对象。而一旦堆中的对象被销毁,我们继续引用这个对象的话,就会出现著名的 NullPointerException,这就是堆的缺点——错误的引用逻辑只有在运行时才会被发现。

栈不灵活,但是很严格,是安全的,易于管理。因为只要上面的引用没有销毁,下面引用就一定还在,所以,在栈中,上面引用永远可以通过下面引用来查找对象,同时如果确认某一区间的内容会一起存在、一起销毁,也可以上下互相引用。在大部分程序中,都是先定义的变量、引用先进栈,后定义的后进栈,同时,区块内部的变量、引用在进入区块时压栈,区块结束时出栈,理解了这种机制,我们就可以很方便地理解各种编程语言的作用域的概念了,同时这也是栈的优点——错误的引用逻辑在编译时就可以被发现。

总之,就是变量和对象的引用存储在栈区中,而对象在存储在堆中

在Windows编程中互斥量与临界区比较类似,请分析一下二者的主要区别。

两者都可以用于同一进程中不同子线程对资源的互斥访问。

互斥量是内核对象,因此还可以用于不同进程中子线程对资源的互斥访问。

互斥量可以很好的解决由于线程意外终止资源无法释放的问题。

第二题:

一个全局变量tally,两个线程并发执行(代码段都是ThreadProc),问两个线程都结束后,tally取值范围。

inttally = 0;//glable

voidThreadProc()

{

for(int i = 1; i <= 50;i++)

tally += 1;

}

答:[50,100]

参考文章:http://blog.csdn.net/dazhong159/article/details/7948327

一个牛逼的链接:http://blog.csdn.net/morewindows/article/details/7392749
程序解答:http://blog.csdn.net/lanyan822/article/details/7587972

原文地址:https://www.cnblogs.com/klb561/p/10660470.html

时间: 2024-10-31 08:43:14

多线程的实现方法的相关文章

Win32 多线程的创建方法,区别和联系

Win32多线程的创建方法主要有: CreateThread() _beginthread()&&_beginthreadex() AfxBeginThread() CWinThread类 一.简介 CreateThread: Win32提供的创建线程的最基础的API,用于在主线程上创建一个线程.返回一个HANDLE句柄(内核对象).在内核对象使用完毕后,一般需要关闭,使用CloseHandle()函数. _beginthread()&&_beginthreadex():_

一种非常简便的实现Android多线程池的方法

开发Android过程中至少会遇到一个主线程,也称UI线程,这个线程是不允许阻塞的,否则会报错,比如最常见的获取网络资源.读写文件等操作,这些耗时操作都不能再主线程使用.这里介绍一个非常高效又非常简单实用的方法ExecutorService类. ExecutorService类可以理解为线程池,开发者可以实例化一个该对象,在其中使用多个异步进行的操作. ExecutorService接口继承了Executor接口,定义了一些生命周期的方法,如下定义. public interface Execu

多线程的创建方法

- (void)viewDidLoad {    [super viewDidLoad]; //第一种开启新的线程调用 mutableTheard    NSThread * t = [[NSThread alloc]initWithTarget:self selector:@selector(mutableTheard) object:nil];    [t start];            //第二种开启新的线程调用 mutableTheard    [NSThread detachNe

Java多线程死锁避免方法

一.什么是死锁当两个或两个以上的线程在执行过程中,因为争夺资源而造成的一种相互等待的状态,由于存在一种环路的锁依赖关系而永远地等待下去,如果没有外部干涉,他们将永远等待下去,此时的这个状态称之为死锁.经典的 "哲学家进餐" 问题很好地描述了死锁状况:5个哲学家去吃中餐,坐在一张圆桌旁,他们有5根筷子(而不是5双),并且每两个人中间放一根筷子,哲学家们要么在思考,要么在进餐,每个人都需要一双筷子才能吃到东西,并在吃完后将筷子放回原处继续思考,有些筷子管理算法 (1) 能够使每个人都能相对

多线程的通信方法

转自 http://www.cnblogs.com/mengyan/archive/2012/08/30/2664607.html 一.进程通信方法 在说明线程通信前,有必要对进程通信进行说明: 进程间通信的方法主要有以下几种:  (1)管道(Pipe):管道可用于具有亲缘关系进程间的通信,允许一个进程和另一个与它有共同祖先的进程之间进行通信.  (2)命名管道(named pipe):命名管道克服了管道没有名字的限制,因此,除具有管道所具有的功能外,它还允许无亲缘关 系 进程间的通信.命名管道

多线程操作的方法(sleep,)setPriority(Thread.MIN_PRIORITY);yield();

在多线程中所有的操作方法都是从Thread类开始的,所有的操作基本都在Thread类中. 第一取得线程名字 a,在Thread类中,可以通过getName()方法,获得线程的名字,可以通过setName()方法设置线程的名字 b,线程名字一般在线程启动前设置,但是也允许为已经运行的线程设置名称,允许2个Thread对象有相 同的名字,但是不推荐,你懂的!!! c,如果程序没有为线程指定名字,则系统自动为线程分配一个名称. package xianchengcaozuo; public class

多线程NSOperation使用方法

/*------------------------------  NSOperation使用   -----------------------------------*/ 重点:操作 NSOperation 和操作队列 NSOperationQueue! { 1.NSOperation(操作)简介: NSOperation: // 本质是对 GCD 的封装, OC 语言. NSOperation 和 GCD 的比较: GCD使用场合: 一些简单的需求,简单的多线程操作. //简单高效 NSO

Java多线程同步的方法

一 synchronized关键字 1.synchronized实现原理: ---基于对象监视器(锁) java中所有对象都自动含有单一的锁,JVM负责跟踪对象被加锁的次数.如果一个对象被解锁,其计数变为0.在任务(线程)第一次给对象加锁的时候, 计数变为1.每当这个相同的任务(线程)在此对象上获得锁时,计数会递增.只有首先获得锁的任务(线程)才能继续获取该对象上的多个锁.每当任务离开时,计数递减,当计数为0的时候,锁被完全释放. Java中每个对象或者类都有一把锁与之相关联,对于对象来说,监视

Java 多线程的实现方法

package com.jckb; /**多线程实现的两种方法 * * @author gx * */ public class Test2 { public static void main(String[] args) { Mythread m = new Mythread(); m.start();// 不能直接调用run方法 // m.run();//是方法调用,不是线程的启动 Thread t = new Thread(new Mythread2()); t.start(); } }

Java多线程之~~~~synchronized 方法

在多线程开发中,总会遇到多个在不同线程中的方法操作同一个数据,这样在不同线程中操作这个数据不同的顺序 或者时机会导致各种不同的现象发生,以至于不能实现你预期的效果,不能实现一致性,这时候就可以使用 synchronized关键字对一个方法来说,这个synchronized能保证所有调用这个方法的线程只有一个正在操作这个方法, 不会出现同时多个线程进入这个方法的情况,下面我们来一个例子说明这个情况. 首先是一个Account类,这个类模拟账户,提供增加工资和减少工资的方法,当然,这个方法是被syn