初学者认识线程和进程

先区分一下几个比较相似的概念吧
进程:表示一个任务。
线程:一种比进程更小的执行单位,依附在进程中,多个线程共享一个进程的资源。
假设有一项任务是修建一条10公里的马路,需要费用100万元,给某建筑公司修建需要10个月,这可以看作是一个进程;然而我需要更快时间完成这项任务,于是我把这个任务分成子任务由10个建筑公司同时修建,每个公司10万元修建一公里,这可以看作是多个线程。


同步——使用者通过单个线程调用服务;该线程发送请求,在服务运行时阻塞,并且等待响应。(打电话)
异步——使用者通过两个线程调用服务;一个线程发送请求,而另一个单独的线程接收响应。 (发短信)
举个例子:普通B/S模式(同步)AJAX技术(异步)
同步:提交请求->等待服务器处理->处理完毕返回 这个期间客户端浏览器不能干任何事
异步: 请求通过事件触发->服务器处理(这是浏览器仍然可以作其他事情)->处理完毕  


线程的同步:
由于同一进程的多个线程共享同一片存储空间,在带来方便的同时,也带来了访问冲突这个严重的问题.
在一个对象中,用synchonized声明的方法为同步方法,每个类实例对应一把锁
每个 synchronized方法一旦执行,就独占该锁,直到从该方法返回时才将锁释放。
这种机制确保了同一时刻对于每一个类实例中,其所有声明为 synchronized 的成员方法中至多只有一个处于可执行状态(思考一下,没有声明为synchronized 的方法,可不可以访问该类的实例呢?).
补充: 在Java 中,不光是类实例,每一个类也对应一把锁,这样我们也可将类的静态成员函数声明为 synchronized,以控制其对类的静态成员变量的访问。

synchronized 方法的缺陷:若将一个大的方法声明为synchronized 将会大大影响效率,典型地,若将线程类的方法 run() 声明为 synchronized ,由于在线程的整个生命期内它一直在运行,因此将导致它对本类任何 synchronized 方法的调用都永远不会成功。
典型地,若将线程类的方法 run() 声明为 synchronized,
由于在线程的整个生命期内它一直在运行,因此将导致它对本类任何 synchronized 方法的调用都永远不会成功。
缺陷解决办法:
synchronized块:通过 synchronized关键字来声明synchronized 块。语法如下:
synchronized(syncObject) {
//允许访问控制的代码 }
synchronized 块是这样一个代码块,其中的代码必须获得对象 syncObject (如前所述,可以是类实例或类)的锁方能执行,由于可以针对任意代码块,且可任意指定上锁的对象,故灵活性较高。(给一个对象加锁时,要考虑该实例的所有方法,同时也要注意死锁,有时间会更新关于多线程同步带来的死锁现象)

线程的阻塞:
为了解决对共享存储区的访问冲突,Java 引入了同步机制,多个线程对共享资源的访问,同步机制已经不够了,因为在任意时刻所要求的资源不一定已经准备好了被访问,反过来,同一时刻准备好了的资源也可能不止一个。为了解决这种情况下的访问控制问题,Java 引入了对阻塞机制的支持。
阻塞指的是暂停一个线程的执行以等待某个条件发生,Java 提供了大量方法来支持阻塞
sleep() 方法suspend() 和 resume() 方法 yield() 方法
前面叙述的所有方法,阻塞时都不会释放占用的锁!!!
前面叙述的所有方法都可在任何位置调用,
但是wait() 和 notify() 方法却必须在 synchronized 方法或块中调用,
原因如下:锁是任何对象都具有的!!!
调用任意对象的 wait() 方法导致线程阻塞,并且该对象上的锁被释放!!!
只有在synchronized 方法或块中当前线程占有锁,才有锁可以释放。同样的道理,调用这一对方法的对象上的锁必须为当前线程所拥有,这样才有锁可以释放。





猜你喜欢

转载自87983133.iteye.com/blog/2246427