黑马程序员技术交流社区

标题: 多线程的疑问 [打印本页]

作者: 杜佳瑞    时间: 2012-9-3 14:08
标题: 多线程的疑问
本帖最后由 杜佳瑞 于 2012-9-3 14:13 编辑

今天看书有一个很有意思的例题,其实说服自己理解的理由很简单,但是还是想叫大家来看一下,有没有更好的解释:
class SetNameThreadDemo extends Thread
{
        public void run()
        {
                for(int i=0;i<10;i++)
                {
                         printMsg();
                }
         }
        public void printMsg()
        {
                //  获得运行此代码的线程的引用
               Thread t = Thread.currentThread();
                    String name = t.getName();
                    System.out.println("name = "+name);
        }
}
class ThreadDemo9_3
{
        public static void main(String args[])
        {
                SetNameThreadDemo tt = new SetNameThreadDemo();
                         //  在这里设置线程的名称
                tt.setName("test thread");
                tt.start(); //开启线程,通过线程中的run()方法调用printMsg() 方法
                for(int i=0;i<10;i++)
                {
                        tt.printMsg(); //主函数中直接调用printMsg() 方法,虽然还是tt这个线程对象调用,但是不通过run()方法,打印出的名字是main。也许你会说在主线程里调用printMsg() 方法,当然打印主线程的名字,可是这里使用tt调用的呀,这应该怎么理解呢?
                }
        }
}

作者: 杨卫腾    时间: 2012-9-3 14:51
  1. public void printMsg()
  2.         {
  3.                 //  获得运行此代码的线程的引用
  4.                Thread t = Thread.currentThread();
  5.                     String name = t.getName();
  6.                     System.out.println("name = "+name);
  7.         }
复制代码
其实我是这样理解的,tt.start(); 开启了一个线程,下边的for循环执行的却是主线程代码,tt.printMsg();仅仅是一个方法,在主线程中运行,这个里边有获得运行此代码的线程的引用,所以打印的当前主线程的名称。我是这样理解的。
作者: 杨卫腾    时间: 2012-9-3 14:51
  1. public void printMsg()
  2.         {
  3.                 //  获得运行此代码的线程的引用
  4.                Thread t = Thread.currentThread();
  5.                     String name = t.getName();
  6.                     System.out.println("name = "+name);
  7.         }
复制代码
其实我是这样理解的,tt.start(); 开启了一个线程,下边的for循环执行的却是主线程代码,tt.printMsg();仅仅是一个方法,在主线程中运行,这个里边有获得运行此代码的线程的引用,所以打印的当前主线程的名称。我是这样理解的。
作者: 张飞年    时间: 2012-9-3 15:38
整个过程应该是这样的:
    程序加载main函数,再生成线程任务对象SetNameThreadDemo并指向tt,接着设置对象的继承的成员属性setName(),接着tt.start()开启新线程与main线程开始抢资源运行,因为没有同步所以会出现一些安全问题(在printMsg这里只有一个sop name的语句,故看起来正常),与此同时main线程也执行后面的语句,执行tt.printMsg()方法是SetNameThreadDemo正常调用自己的成员方法,只不过执行线程是main,此时打印的线程名字也当然就是main了,再详细说就是我们打印的是线程名而非调用对象名字。
作者: 张飞年    时间: 2012-9-3 15:39
整个过程应该是这样的:
    程序加载main函数,再生成线程任务对象SetNameThreadDemo并指向tt,接着设置对象的继承的成员属性setName(),接着tt.start()开启新线程与main线程开始抢资源运行,因为没有同步所以会出现一些安全问题(在printMsg这里只有一个sop name的语句,故看起来正常),与此同时main线程也执行后面的语句,执行tt.printMsg()方法是SetNameThreadDemo正常调用自己的成员方法,只不过执行线程是main,此时打印的线程名字也当然就是main了,再详细说就是我们打印的是线程名而非调用对象名字。
作者: 武庆东    时间: 2012-9-3 15:56
   tt.printMsg(); //主函数中直接调用printMsg() 方法,虽然还是tt这个线程对象调用,但是不通过run()方法,打印出的名字是main。也许你会说在主线程里调用printMsg() 方法,当然打印主线程的名字,可是这里使用tt调用的呀,这应该怎么理解呢?
当java程序开始运行后,程序至少会创建一条主线程,主线程的线程执行体不是有run方法确定的,而是由main方法来确定:main方法的方法体代表主线程的线程执行体!
作者: 杜佳瑞    时间: 2012-9-3 19:02
张飞年 发表于 2012-9-3 15:39
整个过程应该是这样的:
    程序加载main函数,再生成线程任务对象SetNameThreadDemo并指向tt,接着设置对 ...

最后一句话很靠谱,应该就是这样理解了。
问题已解决




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2