多线程(二)

来源:互联网 发布:叛逆的鲁鲁修朱雀知乎 编辑:程序博客网 时间:2024/05/13 07:21

多线程的常用函数和线程同步

1、 常用函数

void run()  //创建该类的子类时必须实现的方法

void start() //开启线程的方法

static void sleep(long t) //释放CPU的执行权,不释放锁

static void sleep(long millis,int nanos)

final void wait()//释放CPU的执行权,释放锁

final void notify()

static void yied()//可以对当前线程进行临时暂停(让线程将资源释放出来)

public final void stop()//结束线程,(由于安全的原因已过时)

public final void join()//让线程加入执行,执行某一线程join方法的线程会被冻结,等待某一线程执行结束,该线程才会恢复到可运行状态

public final boolean isAlive()//判断线程是否死亡

 

注意:结束线程原理---就是让run方法结束。而run方法中通常会定义循环结构,所以只要控制住循环即可。

 

2、 线程的同步

由于线程是共享资源的,并在运行时有随机性,所以在多个线程同步时就有可能出现数据访问的冲突问题。

临界资源:多个线程间共享的数据称为临界资源

 

互斥锁

每个对象都对应于一个可称为“互斥锁”的标记,这个标记用来保证在任一时刻,只能有一个线程访问该对象。

Java对象默认是可以被多个线程共用的,只是在需要时才启动“互斥锁”机制,成为专用对象。

关键字synchronized用来与对象的互斥锁联系

当某个对象用synchronized修饰时,表明该对象已启动“互斥锁”机制,在任一时刻只能由一个线程访问,即使该线程出现堵塞,该对象的被锁定状态也不会解除,其他线程任不能访问该对象。

二种用法:

(1)、public void push(char c){
                     sychronized(this){
                            data[index]=c;
                            index++
                     }
       }

(2)、public synchronized char pop(){

             index--;

              return data[index];

}

 

同步好处:决了线程安全问题

同步弊端:一、降低了运行效率(判断锁是较为消耗资源的)二、同步嵌套,容易出现死锁

死锁:两个线程A、B用到同一个对象s(s为共享资源),且线程A在执行中要用到B运行后所创造的条件。在这种前提下A先开始运行,进入同步块后,对象s被锁定,接着线程A因等待B运行结束而进入阻塞状态,于是B开始运行,但因无法访问对象s,线程B也进入阻塞状态,等待s被线程A解锁。最终的结果:两个线程互相等待,都无法运行。

 

容易出现死锁的两种情况

情况1:子线程t并未锁定任何共享资源,只是因为无法访问共享资源sb而陷入阻塞状态。主线程则是因为串行加入了子线程t而进入阻塞状态,且必须要等线程t运行完毕才可能恢复运行并解除对共享资源的锁定,双方僵持、互不相让,导致进入“死锁”状态。

 

情况2:这是线程死锁的典型表现,两个以上线程并发运行,他们均因其他线程锁定了自己运行所需资源而陷入阻塞状态,同时自己也锁定了其他线程所需资源。