一个线程开始执行后就进入等待,然后另外一个线程来唤醒它
代码如下:
package com.zcj.thread02;
public class Thread01 {
private static Object object= new Object();
public static void main(String[] args) {
ThreadA theA = new ThreadA(object);
ThreadB threadB = new ThreadB(object);
theA.start();
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
threadB.start();
}
}
class ThreadA extends Thread{
private Object object;
public ThreadA(Object object){
this.object=object;
}
@Override
public void run(){
synchronized (object) {
try {
System.out.println("我开始等待。。。");
object.wait();
System.out.println("我被唤醒了,不再等待");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
class ThreadB extends Thread{
private Object object;
public ThreadB(Object object){
this.object=object;
}
@Override
public void run(){
synchronized (object) {
object.notify();
}
}
}
一个消费者和一个生产者的同步问题:
package com.zcj.thread02;
public class Thread01 {
public int count= 0;
public void produce(){
synchronized (this) {
if(count==1){
try {
this.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("我生产商品!");
count=1;
this.notify();
}
}
public void consumer(){
synchronized (this) {
if(count==0){
try {
this.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("我消费商品");
count=0;
this.notify();
}
}
public static void main(String[] args) {
Thread01 thd = new Thread01();
ThreadA threadA = new ThreadA(thd);
ThreadB threadB = new ThreadB(thd);
threadA.start();
threadB.start();
}
}
class ThreadA extends Thread{
private Thread01 thd;
public ThreadA(Thread01 thd){
this.thd=thd;
}
@Override
public void run(){
while(true){
thd.produce();
}
}
}
class ThreadB extends Thread{
private Thread01 thd;
public ThreadB(Thread01 thd){
this.thd=thd;
}
@Override
public void run(){
while(true){
thd.consumer();
}
}
}
多个生产者和多个消费者的例子如下:注意其中变化的部分,while和notifyAll();不过使用synchronized有个问题就是唤醒的时候不能有所指定的唤醒对应的线程:
首先解释下这里为什么会使用while语句来判断:因为如果在用if的时候,当线程获得锁再次进入临界区就不会再去判断条件了,多个线程一起工作的时候就可能导致count的值超过1,另外在多个消费线程在消费的时候也可能导致下面count最终消费后的数量低于0,这样不就不符合逻辑了。使用notifyAll的原因是比如多个生产者和多个消费者一起工作,假如某个生产者开始等待,他唤醒的可能是另外一个生产者,这样另外一个生产者也进入等待,就存在一种情况导致消费者一直得不到唤醒,任务就进行不了了
package com.zcj.thread02;
public class Thread01 {
public int count= 0;
public void produce(){
synchronized (this) {
while(count==1){
try {
this.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("我生产商品!");
count=1;
this.notifyAll();
}
}
public void consumer(){
synchronized (this) {
while(count==0){
try {
this.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("我消费商品");
count=0;
this.notifyAll();
}
}
public static void main(String[] args) {
Thread01 thd = new Thread01();
ThreadA threadA = new ThreadA(thd);
ThreadA threadA1 = new ThreadA(thd);
ThreadB threadB = new ThreadB(thd);
ThreadB threadB1 = new ThreadB(thd);
threadA.start();
threadA1.start();
threadB.start();
threadB1.start();
}
}
class ThreadA extends Thread{
private Thread01 thd;
public ThreadA(Thread01 thd){
this.thd=thd;
}
@Override
public void run(){
while(true){
thd.produce();
}
}
}
class ThreadB extends Thread{
private Thread01 thd;
public ThreadB(Thread01 thd){
this.thd=thd;
}
@Override
public void run(){
while(true){
thd.consumer();
}
}
}