有关Object之wait(),notify() 和notifyAll() 以及Thread之sleep(),join()和yield()

来源:互联网 发布:乔布简历 知乎 编辑:程序博客网 时间:2024/04/23 20:46

1. Object的wait(),notify()和notifyAll()
主要用于在多线程情况下,同步控制访问共享资源使用。
调用wait() 函数后,导致当前线程处于等待状态,只有通过notify()或者notifyAll()方法,或者在调用wait()函数时,设置超时时间timeout,等待超时时间到了,才能使阻塞在该对象上的线程唤醒,进行运行。

也就是说wait()或notify() 会对对象的“锁标志”进行操作,wait()执行后,其线程会释放掉它所占的"锁标志",从而使其它线程可以访问之前锁在同一对象的synchronized 同步函数或者同步代码块。

也就是wait() 或 notify() 主要与synchronized关键字配套使用。


2. synchronized关键字
对于synchronized关键字,目的在于进行同步控制,保证只有一个线程可以进入,当另一个线程需要访问synchronized同步代码块时,需要等待之前的线程执行完,离开synchronized同步块或者调用wait,该线程才能进入需要访问的synchronized代码块。
使用的关键是:确保所有线程都锁在同一个对象上,否则锁在不同对象上的多个线程访问synchronized代码块没有任何影响。
因此这里锁的对象通常有**.class, this 或者一个Object对象上。

例如:

2.1 锁在Class对象上。
这样其它线程就不能调用该类的其它静态synchronized方法或者执行锁在synchronized(Foo.class)的代码,但可以调用该类中所在其它锁在非类Class对象的代码块,
public synchronized static void method1()   // 同步的static 函数   { //TODO  }   public void method2()   {      synchronized(Foo.class)  }   


2.2 锁在this对象
public synchronized void method1()   // 同步的函数   { //TODO  }   public void method2()   {      synchronized(this)  } 


2.3 所在其它如Object对象上
如:
private Object object1 = new Object();public void execute(){    synchronized(object1){       //TODO    }}

2.4 synchronized同步方法 与 synchronized 同步代码块的区别:
1)synchronized同步方法,是粗粒度的并发控制,某一个时刻只能有一个线程执行该synchronized方法。
2) synchronized同步代码块,是更为细粒度的并发控制,其只是锁定了该代码块,代码块外面的代码还是可以被访问。

3. 在Java JDK5中有三种方式可以保证线程安全ThreadLocal, synchronized, Lock。


3.1 ThreadLocal 

采用的是一种空间换时间的策略,为每个线程都创建一个相应的副本。


3.2 synchronized 

可以在方法或者代码块中,把需要共享访问的资源进行同步控制。


3.3 Lock 
其吞吐量要比synchronized方法更好
相比synchronized
1)当代码块被同步了,如果不想等了,可以进行unlock而,synchronized无法实现;
2)性能上Lock更优质,并且还提供了在激烈争用情况下更好的性能。


4.Thread的join , sleep和yield
4.1 join() 方法主要用于使该线程彻底结束,当线程执行完成后才会运行join()后面的语句。

   public final void join() throws InterruptedException {        VMThread t = vmThread;        if (t == null) {            return;        }        synchronized (t) {            while (isAlive()) {                t.wait();            }        }    }

4.2 sleep() 
使当前线程交出CPU占用权,暂停执行一段时间,让其它同优先级或低优先级线程有机会运行。

4.3 yield()
作用与sleep类似。
其:先检测当前是否有相同优先级的线程处于可运行状态,如有,则把CPU的占有权交给该线程,否则继续运行原来的线程,它把
运行机会让给了同等级的其它线程。
但有以下不同:
1)sleep让当前线程休眠一段时间后,进行不可运行状态,让出的时间可以有程序设定,而yield不可以设置。
2)yield 执行后,当前线程仍旧处于可运行状态,所以不可能让低优先级的线程此时获取CPU使用权。
0 0
原创粉丝点击