2 u013096859 u013096859 于 2016.03.02 22:35 提问

多线程中this关键字的问题
 package wintervacation.multithreading;

/**
 * Created by wangw on 2016/3/2.
 * 消费者和生产者的例子,用于说明线程之间的通信
 * 把生产者和消费者作为两个线程
 * 仓库作为一个类,有装入生产者生产的商品和向消费者提供商品两个方法
 */
public class ConsumerAndProductor {
    public static void main(String[] args) {
        Repo repo = new Repo();
        ComsumerThread comsumerThread = new ComsumerThread(repo);
        comsumerThread.start();
        ProductorThread productorThread = new ProductorThread(repo);
        productorThread.start();
    }
}

class Repo {
    //仓库可以容纳6件商品
    char[] data = new char[6];
    int index = 0;

    public synchronized void in(char c) {
        if (index == 6) {
            try {
                this.wait();
                System.out.println("-----" + this);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        data[index++] = c;
        System.out.println("生产了产品" + c);
        this.notify();
    }

    public synchronized char out() {
        if (index == 0) {
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        index--;
        System.out.println("消费了产品" + data[index]);
        this.notify();
        return data[index];
    }
}

class ComsumerThread extends Thread {
    Repo repo;

    ComsumerThread(Repo repo) {
        this.repo = repo;
    }

    @Override
    public void run() {
        for (int i = 0; i < 20; i++) {
            char c = (char) (Math.random() * 26 + 'A');
            repo.in(c);
            try {
                Thread.sleep((int) (Math.random() * 10));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

class ProductorThread extends Thread {
    Repo repo;

    ProductorThread(Repo repo) {
        this.repo = repo;
    }

    @Override
    public void run() {
        for (int i = 0; i < 20; i++) {
            repo.out();
            try {
                Thread.sleep((int) (Math.random() * 100));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

图片说明
运行结果:
图片说明
既然是有wait方法,那就应该是对应的线程对象吧,可是打印出来又是自己创建的Repo对象,懵了

2个回答

wojiushiwo945you
wojiushiwo945you   Ds   Rxr 2016.03.03 07:56
已采纳
   this是指当前对象本身,你给出的这个in方法是你的Repo类的,你通过这个对象调用in方法,肯定这个方法中的this对象就是这个仓库对象啊。所有类的方法中出现的this都是这个方法调用时.操作前面的对象。这就是为什么我们调用类的方法是必须先创建一个对象,然后通过对象.方法来调用的原因。
u013096859
u013096859 哦哦哦,总在看线程这一块,把wait()方法当作Thread独有的方法了,谢谢啦~~
接近 2 年之前 回复
wojiushiwo945you
wojiushiwo945you 回复顽逗: wait方法是Object类的,而Object类是所有类的父类,当然Repo类继承了这个方法的啊。
接近 2 年之前 回复
u013096859
u013096859 对啊,但是repo没有wait方法啊,它怎么能.wait()呢
接近 2 年之前 回复
broust
broust   2016.03.02 23:03

你在线程里调用了in方法,对应的对象是repo

u013096859
u013096859 恩恩,谢谢,明白了
接近 2 年之前 回复
broust
broust 回复顽逗: wait是Object类的,正如@毕小宝 所说。in方法,锁的是repo对象本身,this.wait刚好释放repo.
接近 2 年之前 回复
u013096859
u013096859 对啊,但是repo没有wait方法啊,它怎么能.wait()呢
接近 2 年之前 回复
Csdn user default icon
上传中...
上传图片
插入图片