java线程的休眠和回复

sleep()方法:表示放弃当前cpu的资源,使当前线程不占用计算机的任何资源。如果当前线程获取到了锁,sleep()方法是不会放弃锁的,如果线程被打断会抛出InterruptException异常。

join()方法:当一个线程对接的join的方法被调用时,调用他的线程会被挂起,直到这个线程对象完成它的任务。

代码:

public class Test3 {

    public static void main(String[] args) {
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("线程开始执行");
                try {

                    TimeUnit.SECONDS.sleep(3);
                } catch (InterruptedException e) {

                    e.printStackTrace();

                }
                System.out.println("线程执行结束");

            }
        });
        System.out.println("主线程执行");
        thread.start();
        try {
            thread.join();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        System.out.println("主线程结束");
    }

}

执行结果:

主线程执行
线程开始执行
线程执行结束
主线程结束

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;
            }
        }
    }

可以看出join方法里一直在判断 线程isAlive(),如果存活就wait(0),把线程处于等待状态,如果线程没有执行完成,那么join()这个方法就一直没有执行问,主线程也不会继续往下执行。

wait()方法:线程必须在同步代码块(synchronized)中调用wait()方法,如果在同步代码块之外调用wait()方法,jvm将会抛出IllegalMonitorStateException。当一个线程调用wait()方法时,jvm会把这个线程陷入休眠,并释放掉锁,同时允许其他线程得到锁。

notify()或notifyAll():在同步代码块中调用这2个方法可以唤醒调用wait()的线程。

列子:

扫描二维码关注公众号,回复: 2411275 查看本文章
public class Computer {

    private int counter = 0;

    public synchronized void producer() {
        while (true) {
            if (counter >= 10) {
                try {
                  
                    wait();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            } else if (counter < 2) {
                for (int i = 0; i < 10; i++) {
                    counter++;
                    System.out.println("生产了一台电脑当前还有" + counter);
                }
            }
            notifyAll();
        }

    }

    public synchronized void consumer() {
        while (true) {
            if (counter == 0) {
                try {
                    wait();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            } else if (counter > 0) {
                while (counter > 0) {
                    counter--;
                    System.out.println("消费一台电脑当前还有" + counter);
                }
            }
            notifyAll();
        }
    }

    public int getCounter() {
        return counter;
    }

    public void setCounter(int counter) {
        this.counter = counter;
    }

    public static void main(String[] args) {
        Computer computer = new Computer();
        Thread producer = new Thread(new Producer(computer));
        Thread consumer = new Thread(new Consumer(computer));
        producer.start();
        consumer.start();
    }

}
public class Consumer implements Runnable{

  private Computer computer;
    
    public Consumer(Computer computer) {
        super();
        this.computer = computer;
    }



    @Override
    public void run() {
    
        computer.consumer();
        
    }

}
public class Producer implements Runnable{

    private Computer computer;
    
    public Producer(Computer computer) {
        super();
        this.computer = computer;
    }



    @Override
    public void run() {
      
         computer.producer();
        
    }
     
    
}

输出结果:

生产了一台电脑当前还有8
生产了一台电脑当前还有9
生产了一台电脑当前还有10
消费一台电脑当前还有9
消费一台电脑当前还有8
消费一台电脑当前还有7
消费一台电脑当前还有6
消费一台电脑当前还有5
消费一台电脑当前还有4
消费一台电脑当前还有3
消费一台电脑当前还有2

在ReentrantLock挂起和唤醒线程需要使用Condition,一个ReentrantLock可以有多个Condition。调用await()使线程挂起并释放掉锁,signalAll()会唤醒线程。

修改Compuetr的代码 Producer 和 Consumer 代码 不变:

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

public class Computer {

    private int counter = 0;

    private ReentrantLock lock;

    private Condition producerC;

    private Condition consumerC;

    private Computer(ReentrantLock lock) {
        this.lock = lock;
        producerC = lock.newCondition();
        consumerC = lock.newCondition();
    }

    public void producer() {
        while (true) {
            try {lock.lock();
                if (counter >= 10) {
                    try {
                        //线程挂起 并释放掉锁
                        producerC.await();
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                } else if (counter < 2) {
                    for (int i = 0; i < 10; i++) {
                        counter++;
                        System.out.println("生产了一台电脑当前还有" + counter);
                    }
                }
                //把线程唤醒 线程需要重新获取锁
                consumerC.signalAll();
            } finally {
                lock.unlock();
            }
        }

    }

    public void consumer() {
        while (true) {
            try {lock.lock();
                if (counter == 0) {
                    try {  //线程挂起 并释放掉锁
                        consumerC.await();
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                } else if (counter > 0) {
                    while (counter > 0) {
                        counter--;
                        System.out.println("消费一台电脑当前还有" + counter);
                    }
                }
              //把线程唤醒 线程需要重新获取锁
                producerC.signalAll();

            } finally {
                lock.unlock();
            }
        }

    }

    public int getCounter() {
        return counter;
    }

    public void setCounter(int counter) {
        this.counter = counter;
    }

    public static void main(String[] args) {
        ReentrantLock lock = new ReentrantLock();
        Computer computer = new Computer(lock);
        Thread producer = new Thread(new Producer(computer));
        Thread consumer = new Thread(new Consumer(computer));
        producer.start();
        consumer.start();

    }

}

猜你喜欢

转载自blog.csdn.net/hyhanyu/article/details/81218990
今日推荐