浅谈Java中线程的生命周期

2021/11/11 17:10:55

本文主要是介绍浅谈Java中线程的生命周期,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

一:Java生命周期汇总

Java中线程的生命周期状态主要为新建,就绪,运行,阻塞,死亡。

二:各状态之间的转化关系

Java中线程各状态之间的转换主要依靠方法来完成:

经典问题:Sleep()和()wait之间有什么区别?

答:sleep()方法用被用于让程序暂停指定的时间,而wait()方法被调用后,线程不会自动苏醒,需要别的线程调用同一个对象上的notify()或者nofifyAl()方法

主要的区别是,wait()释放锁或监视器,然而sleep()不释放任何锁或监视器等。wait被用于线程间通信,而sleep一般来说被用于在执行时引入暂停。

Thread.sleep()让当前线程进入不可运行状态一段时间。线程继续保持它所获取的监视器——即如果线程当前处于同步块或方法中,则没有其他线程可以进入此块或方法。如果另一个线程调用t.interrupt()会唤醒sleep的线程。注意,sleep()是一种静态方法,这意味着它总是影响当前线程(执行睡眠方法的线程)。一个常见的错误是用t.sleep期望不同的线程休眠,但实际上是当前线程休眠。

object.wait()让当前线程进入不可运行状态,如sleep()一样,但不同的是wait方法从一个对象调用,而不是从一个线程调用;我们称这个对象为“锁定对象(lockObj)”。在lockObj.wait()被调用之前,当前线程必须在lockObj上同步(synchronize);然后调用wait()后释放这个锁,并将线程增加到与lockObj相关的“等待名单(wait list)”。然后,另一个在同一个lockObj锁定(synchronize)的方法可以调用lockObj.nofity()。这会唤醒原来等待的线程。基本上,wait() / notify()就像sleep() / interrupt(),只是活动线程不需要直接指向一个睡眠线程,他们只需要共享锁对象(lockObj)。

三:经典线程同步机制

 JAVA:通过同步机制可以解决
* 1.同步代码块
* synchronized(同步监视器){
*     需要被同步的代码,操作共享数据的代码
*     多个线程共同操作的变量叫共享数据
*     同步监视器,俗称锁,任何一个类的对象都能当作锁          要求多个线程必须公用用一把锁
* }
* 2.同步方法
*  如果操作共享数据的代码块声明在一个方法中,我们可以将此方法声明为同步
*  造一个方法,在run()函数重写时调用 public synchronized +函数
*  继承实现多线程同步方法需要将声明的方法变为static,直接加synchronization没用,要保证同步监视器唯一

四:生产者消费者问题

Java实现生产者消费者问题如下:

/**
 * 生产者消费者问题,线程通信的应用
 * 生产者(producer)将产品交给店员(clerk),消费者(Consumer)从店员处取走产品,电源一次只能持有固定数量的产品(比如20),如果生产者试图生产更多的产品
 * 店员会叫生产者停一会,如果点中有空位存放再通知生产者继续生产;如果店中没有产品了,店员会告诉消费者等待一会,如果有产品再通知消费者来取走产品。
 *
 * 分析:  生产者消费者多线程
 *       线程不安全,产品为共享数据
 *       同步机制解决线程安全
 *       线程通信问题
 */
public class Test {
    public static void main(String[] args) {
        Clerk clerk=new Clerk();
        Producer producer=new Producer(clerk);
        Consumer consumer=new Consumer(clerk);
        producer.setName("生产者");
        consumer.setName("消费者");
        producer.start();
        consumer.start();
    }
}
class Clerk{
    public static int produce=0;
    public synchronized void producePro(){
        if(this.produce<20){
            try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            this.produce++;
            System.out.println(Thread.currentThread().getName()+"生产一个产品,剩余"+this.produce);
            notify();
        }
        else {
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    public synchronized void produceCon(){
        if (this.produce > 0) {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            this.produce--;
            System.out.println(Thread.currentThread().getName()+"消耗一个产品,剩余"+this.produce);
            notify();
        }
        else {
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
//生产者生产
class Producer extends Thread{
    Clerk clerk=new Clerk();
    public Producer(Clerk clerk){
        this.clerk=clerk;
    }
    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName()+"生产者开始生产");
        while(true){
            clerk.producePro();
        }
    }
}
//消费者消费
class Consumer extends Thread {
    Clerk clerk=new Clerk();
    public Consumer(Clerk clerk) {
        this.clerk = clerk;
    }

    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName() + "消费者开始消费");
        while (true) {
            clerk.produceCon();
        }
    }
}

刚开始学还不是很熟练,欢迎大家指证。



这篇关于浅谈Java中线程的生命周期的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程