您的位置:首页 > 其它

多线程(多线程需要注意的问题)

2015-10-21 23:03 218 查看
------<a href="http://www.itheima.com" target="blank">Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流! -------

前面介绍了一下多线程,那么我们再来看看关于多线程这块我们有哪些要注意的问题?

我们要先知道多线程的生命周期,我用图来简单说明一下吧~


需要注意的是,开始线程以后会有两条通道,一条是将线程执行完毕,就是到达线程结束.另外一条就是线程阻塞,回到线程就绪状态继续执行,通过一个睡眠将线程进入到阻塞状态.

说到这里,我们来聊一下线程阻塞的问题.这个也就是我们常用的sleep和wait方法.

那么sleep和wait有哪些区别呢?

我们大致从属于的类,它们使用的位置,参数和释放锁这四块来区别一下.

1.类:sleep属于Thread类,而wait属于object类

2.位置:sleep是可以在任意位置使用的,而wait是只能同步代码块的前面使用.

3.参数:sleep是必须要传入参数的,因为只有这样才能将sleep唤醒.而wait是既可以传入参数,也可以不必传入参数,但是如果不传入参数的话,必须在同步代码块后面用notify唤醒该代码块线程,或者用notifyAll唤醒所有线程.

4.释放锁:sleep使用完成是不释放锁的,而wait使用完成是要释放锁的.

----------------------------------------------------------------------------------------------------------------------------------------------------------

静态加锁和非静态加锁是不一样的.它们有什么区别呢,我们来看一下.

其实我们在之前也有提到过,只不过在这里我们来整体了解一下,做一下巩固.

静态的锁是 类名.class,也就是字节码文件,而非静态的锁 是this对象,这个this指代的是调用的那个对象,也就是说你new的谁,那么那个对象就是this.在这个类当中会有一个默认的object类,this会默认的调用object类.

那么为什么静态的锁不能是this呢?

这个问题我们就要从静态的生命周期来考虑,因为静态方法创建的时候还没有对象,连对象都没有,根本就没办法用this指代对象.

那么我们为什么要加锁呢,其实很简单,因为多线程是共享资源的,为了避免出现重复,我们必须要加锁,也就是说,一旦这个线程被我这个进程上锁了,那么你别的进程就不能再使用了.

说到上锁了,我们又会遇到一个开发当中常常会遇到的问题,就是死锁?

死锁是什么,就是锁当中又嵌套了一把锁.用我们生活中的例子来距离吧,比方说你和你的女朋友去吃西餐,但是桌子上呢只有一把餐具,一个刀和一个叉子,你拿着刀,你女朋友拿着叉子,谁都没有办法用餐,你希望你女朋友把叉子给你,你女朋友希望你把到给她,导致两人产生了死锁.无法进行用餐环节.用一段代码来体现一下吧:
public class DeadLock {

/**
* @param args
*/
private static String s1 = "刀";
private static String s2 = "叉子";

public static void main(String[] args) {
new Thread() {
public void run() {
while(true) {
synchronized(s1) {
System.out.println(getName() + "...获取" + s1 + "等待" + s2);
synchronized(s2) {//这步是不会被执行到的
System.out.println(getName() + "...拿到" + s2 + "开吃");
}
}
}
}
}.start();

new Thread() {
public void run() {
while(true) {
synchronized(s2) {
System.out.println(getName() + "...获取" + s2 + "等待" + s1);
synchronized(s1) {//这步是不会被执行到的
System.out.println(getName() + "...拿到" + s1 + "开吃");
}
}
}
}
}.start();
}
}
s1和s2这两个变量都希望获取到对方,可是谁也不让谁,于是他们都处于等待状态,永远不会获取到对方.

注意:sleep和wait在休眠的时候是没有执行权的,因为处于休眠期,其实就是两耳不闻窗外事.

同步代码块和同步方法的区别:

我们可以通过两方面来记忆,一个是锁的位置不同,同步代码块的锁是加在代码块的前面,同步方法的锁是在方法声明上;另外一个是锁对象不同,同步方法的锁可以是任意对象,同步代码块的锁必须是this对象.

如果哪里有欠缺,还望多都海涵!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: