在java多线程中需要用到wait和notify。
这两个操作都必须在同步块内部。
调用wait之后就会在wait位置上卡住,把当前同步的锁释放,从新等待当前对象的锁。
当notify的时候,首先将同步块运行结束,然后释放锁并通知其他wait线程开始进行锁竞争。其他wait线程只有一个可以获得锁。
那notify和notifyAll有什么区别呢?notify是唤醒多个wait线程中的一个并让他继续工作,notifyAll是唤醒所有的wait线程让他们重新进行锁的竞争。使用notify和notifyall的时候需要注意,notify与wait必须是一对一的,需要写程序的时候控制好,避免有wait无notify的情况。使用notifyall的时候是让所有的wait线程有机会(其中一个获取锁,其他的也都获取锁的时候也会继续)向下执行,就需要考虑wait方法后续的资源是否可以使用的情况。
sleep是Thread的静态方法,他不是多线程用的,好多人把他与多线程联系是不正确的。
sleep是使得当前线程卡主等待,跟锁或者同步有关系。
从应用上讲,wait和sleep都是使得线程卡主,都可以通过interrupt打断。
JAVA多线程造成死锁的可能有:
对于一把锁,wait之后忘记notify
对于多把锁,当线程1拿到了A锁,线程2拿到了B锁,这是线程1等待B锁,线程2等待A锁
package spyudemo.thread;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import javax.management.Query;
public class TestQueue {
public LinkedList queueList=new LinkedList();
private SendThread[] sendThreadArr=null;
public TestQueue(int threadNum){
sendThreadArr=new SendThread[threadNum];
for(int i=0;i<threadNum;i++){
sendThreadArr[i]=new SendThread("thread:"+i+" ");
sendThreadArr[i].start();
}
}
public void addInfo(Object objcet){
synchronized (queueList) {
queueList.add(objcet);
queueList.notifyAll();
}
}
public class SendThread extends Thread{
public SendThread(String name){
this.setName(name);
}
public void run(){
while(true){
synchronized (queueList) {
System.out.println(this.getName()+"11111111");
if(queueList.isEmpty()){
try {
System.out.println(this.getName()+"22222222222");
queueList.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//使用notifyALl在这里需要判断是否为空
//使用notify由于是一对一的,这里可以不做判断
if(!queueList.isEmpty()){
Object obj=queueList.removeFirst();
System.out.println(this.getName()+"33333333333333333333");
}
}
}
}
}
public static void main(String[] args){
TestQueue test=new TestQueue(10);
for(int i=0;i<10;i++){
test.addInfo(new Object());
// try {
// Thread.sleep(2000);
// } catch (InterruptedException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
}
}
}