A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 程洋 中级黑马   /  2013-12-13 15:49  /  978 人查看  /  4 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

在线程中:老师讲到同步函数的锁是this;(以前讲this时说的是哪个对象调用,this就是指向哪个对象)而同步的一个前提是必须是相同的锁,若果这里的this值得是线程的话肯定是不对的,但是就是不知道this到底是谁.

评分

参与人数 1技术分 +1 收起 理由
乔兵 + 1

查看全部评分

4 个回复

正序浏览
本帖最后由 还记得梦想吗 于 2013-12-14 04:45 编辑

参见 最下面 同步程序中 消费生产问题的 this 关键字  已用红色字体大写注释
上面 是看到别人举得很好的例子 对this 作了解释
最下面是 毕向东老师视频里的 红字 做了解释 分析
this 一 是指自己本身  及当前对象
      --- 当一个类中要明确指出自己使用对象自己的变量或函数时就加上this
public class Hello {

String s = "Hello";

public Hello(String s)
{
System.out.println("s = " + s);
System.out.println("1 -> this.s = " + this.s);
this.s = s;
System.out.println("2 -> this.s = " + this.s);
}

public static void main(String[] args) {
Hello x="new" Hello("HelloWorld!");
}
}

运行结果:

s = HelloWorld!
1 -> this.s = Hello
2 -> this.s = HelloWorld!

在这个例子中,构造函数Hello中,参数s与类Hello的变量s同名,这时如果直接对s进行操作则是对参数s进行操作。若要对类Hello的成员变量s进行操作就应该用this进行引用。运行结果的第一行就是直接对构造函数中传递过来的参数s进行打印结果; 第二行是对成员变量s的打印;第三行是先对成员变量s赋传过来的参数s值后再打印,所以结果是HelloWorld!


      二、 把this作为参数传递
      --- 当你要把自己当做参数传递给别的对象时,也可以用this

     三、注意匿名类和内部类中的中的this。
        有时候,我们会用到一些内部类和匿名类,如事件处理。当在匿名类用this时,这个this则指的是匿名类或内部类本身。这时如果我们要使用外部类的方法和变量的话,则应该加上外部类的类名。

4。在构造函数中,通过this可以调用同一class中别的构造函数,


详细例子 见 http://wenku.baidu.com/link?url=B0RYJMid0jeMqkxC5ZPv2MfgCOEUu2aEYVQx15agExO09Bww6FjYCjmJZtYxjLTsv8aciGeAXtTZeMzXvozTrlaejC8C8H4zdhMpQHl18-q


package day12;

/*
* 对于多个生产者和消费者。
* 为什么要定义while判断标记。
* 原因:让被唤醒的线程再一次判断标记。
*
* 为什么定义notifyAll,
* 因为需要唤醒对方线程。
* 因为只用notify,容易出现只唤醒本方线程的情况。导致程序中的所有线程都等待。
*
* JDK 1.5 中提供了多线程升级解决方案。
* 将同步Sysnchronized替换成显示Lock操作。
*
* 将Object 中wait,notify , notifyall, 替换成了Condition对象
* 该对象可以Lock锁, 进行获取
*
* 本实例中,实现了只唤醒对方的操作。。
* */
import java.util.*;
import java.util.concurrent.*;

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

public class ProducerConsumerDemo2 {

        /**
         * @param args
         */
        public static void main(String[] args) {
                Resource r = new Resource();
               
                Producer pro = new Producer(r);
                Consumer con = new Consumer(r);
               
                Thread t1 = new Thread(pro);
                Thread t2 = new Thread(pro);
                Thread t3 = new Thread(con);
                Thread t4 = new Thread(con);
               
                t1.start();
                t2.start();
                t3.start();
                t4.start();
               
                //t1 false t1 不需要等待 往里面赋值 130 打印我生产 falg为true 然后t1等着了(放弃资格)
                // t2 t3 t4 都可能抢到资源
                //      -- t2抢到了资源 t2 为true  然后t2 也等待 (放弃资格)  
                //      -- t2 后 t3 抢到了资源 非真 为假 不需要等待 执行打印 正常消费 然后 false 非false为true 然后等待
                //      -- t4  抢到后  非false为true 然后继续等待   只剩下t1 不需要等待 继续生产  
                //      --


        }

}

//资源  产品 Resource
class Resource
{
        private String name;
        private int count = 1;
        private boolean flag = false;
            //t1 t2
        //父类创建子类对象
        private Lock lock = new ReentrantLock();
        
        //一个锁里面可以绑定多个 Condition 对象。。
        private Condition condition_pro = lock.newCondition();
        private Condition condition_con = lock.newCondition();
        
        
        
        public void setName(String name) throws InterruptedException {
                //if(flag)
                try{
                        while(flag){
                                //生产者等待
                                condition_pro.await();
                        }        
                        //this.name是 资源产品         Resource的name                
                        this.name = name + "---"+ count ++;
                        System.out.println(Thread.currentThread().getName()+".....生产者..."+this.name);
                        flag = true;
                        //condition.signalAll();
                        //唤醒对方消费一个线程
                        condition_con.signal();
                                
                }finally {
                        //释放锁的动作一定要执行
                        lock.unlock();
                }
                        
        }        
        
        public void out() throws InterruptedException
        {               
                //while用于循环语句,而if用于判断和分支语句。由于你并没有指明是什么程序,只能泛泛而谈了。if 语句中,常用格式为:if(判断条件){执行语句}上面的结构,只是进行一次判断。
                //While(判断条件)do{执行语句},先进行判断,而运行执行语句。执行语句运行完毕,自动返回继续判断while中的条件是否符合,符合的话,继续运行执行语句,不符合,则退出循环。
                //if(!flag)
                lock.lock();
               
                        try {
                                while(!flag)
                                {
                                        //消费者等待
                                condition_con.await();
                                }
                          //this.name是 资源产品         Resource的name                
                                System.out.println(Thread.currentThread().getName()+".....消费者........"+this.name);
                                flag = false;
                                //唤醒对方生产者一个线程
                                condition_pro.signal();
                                
                        }
                        finally {
                                lock.unlock();
                        }        
               
        }        
        
}

class Producer implements Runnable
{
        private Resource res;
        
        Producer(Resource res)
        {
                //此this是Producer生产者  生产者.产品 Producer.res
                this.res = res;
        }

        @Override
        public void run() {
                while(true)
                {
                        try {
                                res.setName("+商品+");
                        } catch (InterruptedException e) {
                                e.printStackTrace();
                        }
                }
               
        }        
}

class Consumer implements Runnable
{
        private Resource res;
        
        Consumer(Resource res)
        {
                 //此this是Consumer消费者  this.res ==  消费者.产品    消费者.res
                this.res = res;
        }

        @Override
        public void run() {
                while(true)
                {
                        try {
                                res.out();
                        } catch (InterruptedException e) {
                                e.printStackTrace();
                        }
                }
        }
        
}



评分

参与人数 1技术分 +2 收起 理由
乔兵 + 2

查看全部评分

回复 使用道具 举报
回复 使用道具 举报
函数需要被对象调用,那么函数有一个所属对象引用,就是this。
http://user.qzone.qq.com/1107939264/infocenter#!app=4&via=QZ.HashRefresh
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马