在多线程中,往往涉及到资源的共享和利用。但是如何设计线程的执行顺序,是比较关键的问题之一。
一般情况下,我们使用synchronized对线程进行约束,但这样有时也会在资源共享方面出现错误。比如有一个空List,第一个线程负责添加element,第二个线程负责删除element,第三个线程同样删除element。那么这样的话,当执行添加的线程运行完毕,第一个删除的线程会删除掉刚刚添加的元素,List已空。而另一个线程可能会同时获取访问这个非空List的机会,从而会出现对空List进行删除操作并因此造成IndexOutOfBoundsException。那么怎么样才能避免这样的错误出现呢?
一般我们会在删除线程中,添加一个对List的约束,比如synchronized(List){}。然后在该block中增加对List的非空判断(用while,非if),比如while(list.isEmpty()){}。如果是空的,那么List.wait,否则执行删除。这样,可以对List进行安全的操作。在添加线程中,我们同样对List进行约束,当添加一个新element后,List.notifyAll(),这样所有处于wait状态的删除线程会被唤醒,进而进行非空删除。由此可以看出,只有在List非空的时候,delete thread 才会执行删除,否则永远处于wait状态,直到add thread把它notify。