join,yield等关键字的使用

来源:互联网 发布:巨灵数据 金融界 编辑:程序博客网 时间:2024/06/06 07:29

1、join。假如A extends Thread ;A a=new A();a.start();a.join()//在main方法下面.调用了join方法的表示当前线程(在这里是main)需等待a的结束才可以继续执行。join(long mills)也用来指定时间。通常用于为每个小问题分配一个线程,当所有小问题解决后,再调用主线程来进一步操作。

2、sleep方法Thread.sleep()//可以有参数设定阻塞时间,让正在执行的线程暂停一段时间,在这段时间之内不会获得执行的机会,即使系统中没有其他可执行的线程,不会释放线程锁。也就是说如果有synchronized同步快,其他线程仍然不能访问共享数据。注意该方法要捕捉异常。注意sleep只是暂停当前线程,让其它线程有机会执行,所以原先调用的sleep(1000)的线程并不是在睡眠1秒后立即执行。而是回到可执行状态。至于是否执行,由jvm调度。

3、yield方法(让步)

跟sleep方法有点相似,但是它不会阻塞该线程,只是将该线程转入就绪状态,让系统的线程调度重新调度一次,所以某个线程调度过了后还可能重新调度出来执行,当前线程放弃CPU,开始睡眠,在睡眠中不会释放锁。但是注意的是yield只会给机会那些优先级高于或等于当前线程的处于就绪状态的线程执行,yield没有异常抛出,sleep具有更好移植性,通常不建议用yield方法来控制并发程序的执行。

4、wait()和notify()、notifyAll()

这三个方法用于协调多个线程对共享数据的存取,所以必须在synchronized语句块内使用。synchronized关键字用于保护共享数据,阻止其他线程对共享数据的存取,但是这样程序的流程就很不灵活了,如何才能在当前线程还没退出synchronized数据块时让其他线程也有机会访问共享数据呢?此时就用这三个方法来灵活控制。

wait()方法使当前线程暂停执行并释放对象锁标示,让其他线程可以进入synchronized数据块,当前线程被放入对象等待池中。当调用notify()方法后,将从对象的等待池中移走一个任意的线程并放到锁标志等待池中,只有锁标志等待池中线程能够获取锁标志;如果锁标志等待池中没有线程,则notify()不起作用。

notifyAll()则从对象等待池中移走所有等待那个对象的线程并放到锁标志等待池中。wait是指在一个已经进入了同步锁的线程内,让自己暂时让出同步锁,以便其他正在等待此锁的线程可以得到同步锁并运行,只有其他线程调用了notify方法(notify并不释放锁,只是告诉调用过wait方法的线程可以去参与获得锁的竞争了,但不是马上得到锁,因为锁还在别人手里,别人还没释放。如果notify方法后面的代码还有很多,需要这些代码执行完后才会释放锁,可以在notfiy方法后增加一个等待和一些代码,看看效果),调用wait方法的线程就会解除wait状态和程序可以再次得到锁后继续向下运行


由于等待一个锁定线程只有在获得这把锁之后,才能恢复运行,所以让持有锁的线程在不需要锁的时候及时释放锁是很重要的。在以下情况下,持有锁的线程会释放锁:

1. 执行完同步代码块。

2. 在执行同步代码块的过程中,遇到异常而导致线程终止。

3. 在执行同步代码块的过程中,执行了锁所属对象的wait()方法,这个线程会释放锁,进行对象的等待池。

     除了以上情况外,只要持有锁的此案吃还没有执行完同步代码块,就不会释放锁。因此在以下情况下,线程不会释放锁:

1.在执行同步代码块的过程中,执行了Thread.sleep()方法,当前线程放弃CPU,开始睡眠,在睡眠中不会释放锁。

2. 在执行同步代码块的过程中,执行了Thread.yield()方法,当前线程放弃CPU,但不会释放锁。

3.在执行同步代码块的过程中,其他线程执行了当前对象的suspend()方法,当前线程被暂停,但不会释放锁。但Thread类的suspend()方法已经被废弃。

     避免死锁的一个通用的经验法则是:当几个线程都要访问共享资源A、B和C时,保证使每个线程都按照同样的顺序去访问他们,比如都先访问A,再访问B和C。

     java.lang.Object类中提供了两个用于线程通信的方法:wait()和notify()。需要注意到是,wait()方法必须放在一个循环中,因为在多线程环境中,共享对象的状态随时可能改变。当一个在对象等待池中的线程被唤醒后,并不一定立即恢复运行,等到这个线程获得了锁及CPU才能继续运行,又可能此时对象的状态已经发生了变化。


ps:可以用过setPriority(),getPriority()来分别设置和得到线程的优先级,默认是NORM_PRIORITY,MAX_PRIORITY:10;MIN_PRIORITY的值是1,尽量避免直接指定线程优先级,而应该用上面三个常量。优先级高,代表获得执行的机会更高而已,不代表优先级低的无法执行,一般是两者都有,优先级高的比例相对来说要大。


0 0
原创粉丝点击