Thread.join
public final synchronized void join(long millis)
throws InterruptedException {
long base = System.currentTimeMillis();
long now = 0;
if (millis < 0) {
throw new IllegalArgumentException("timeout value is negative");
}
if (millis == 0) {
while (isAlive()) {
wait(0);
}
} else {
while (isAlive()) {
long delay = millis - now;
if (delay <= 0) {
break;
}
wait(delay);
now = System.currentTimeMillis() - base;
}
}
}
public final void join() throws InterruptedException {
join(0);
}
join是Thread的一个方法,作用是等待线程结束,可填参数millis(等待时间),不填时,默认是0(注意0表示一直等待,大于0表示等待指定的时间).join方法会一直阻塞到指定时间,当然如果线程在指定时间之前就完成则会提前返回.
join方法还会抛出一个InterruptedException,这是当前线程被中断时抛出异常,而不是join方法属于的线程对象被中断.
如果希望在一个线程完成后再做其他操作就可以使用join
wait
wait方法是Object对象所拥有的方法,调用它会使当前线程进入等待,之后必须调用对象的notify或者notifyAll才能使线程停止等待.它也有时间参数,不填默认是0,就是一直等待.
在调用wait方法之前必须获得该对象的锁,不然会抛异常java.lang.IllegalMonitorStateException
.调用notify会唤醒一个在等待的线程,notifyAll会唤起所有等待的线程
@Test
public void testNotify() throws Exception
{
Object obj = new Object();
int capacity =10;
Thread[] threads = new Thread[capacity];
for (int i = 0; i <threads.length ; i++)
{
threads[i] = new Thread(()->
{
try
{
// System.out.println(Thread.currentThread().getName()+" 0");
synchronized (obj)
{
// System.out.println(Thread.currentThread().getName()+" 1");
obj.wait();
// System.out.println(Thread.currentThread().getName()+" 2");
}
System.out.println(Thread.currentThread().getName()+" 3");
} catch (InterruptedException e)
{
e.printStackTrace();
}
});
threads[i].start();
}
Thread.sleep(1000);
int beforeCount = Thread.activeCount();
synchronized (obj)
{
obj.notify();
}
Thread.sleep(1000);
int afterCount = Thread.activeCount();
System.out.println("before:"+beforeCount+" after:"+afterCount);
assertEquals(beforeCount-1,afterCount);
}
@Test
public void testNotifyAll() throws Exception
{
Object obj = new Object();
int capacity =10;
Thread[] threads = new Thread[capacity];
for (int i = 0; i <threads.length ; i++)
{
threads[i] = new Thread(()->
{
try
{
// System.out.println(Thread.currentThread().getName()+" 0");
synchronized (obj)
{
// System.out.println(Thread.currentThread().getName()+" 1");
obj.wait();
// System.out.println(Thread.currentThread().getName()+" 2");
}
System.out.println(Thread.currentThread().getName()+" 3");
} catch (InterruptedException e)
{
e.printStackTrace();
}
});
threads[i].start();
}
Thread.sleep(1000);
int beforeCount = Thread.activeCount();
synchronized (obj)
{
obj.notifyAll();
}
Thread.sleep(1000);
int afterCount = Thread.activeCount();
System.out.println("before:"+beforeCount+" after:"+afterCount);
assertEquals(beforeCount-capacity,afterCount);
}