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(); } } }
刚开始学还不是很熟练,欢迎大家指证。