关于子线程的交互,线程的run方法与start方法的区别

来源:互联网 发布:量化分析师python日记 编辑:程序博客网 时间:2024/06/06 00:35

1.如何实现子线程与子线程的交互(Timer,加Hanlder 实现)
2.另外线程的run方法与start方法的区别


子线程的交互


class MyThread extends Thread {        public Handler mHandler;        @Override        public void run() {            //每一个线程都只能有一个Looper 对象            // 不实例化则不能实例化Handler;            Looper.prepare();            //1000ms之后发送一个空的消息            new Timer().schedule(new TimerTask() {                @Override                public void run() {                    myThread2.mHandler2.sendEmptyMessage(0x123);                    Log.i("TAG","### current MyThread2 = " + Thread.currentThread().getName());                }            },1000);            //无线循环读取消息            Looper.loop();        }    }    class MyThread2 extends Thread {        public Handler mHandler2;        @Override        public void run() {            Looper.prepare();            mHandler2 = new Handler() {                @Override                public void handleMessage(Message msg) {                    super.handleMessage(msg);                    if (msg.what == 0x123) {                        Log.i("TAG", "### receive come from MyThread --- This is Test ! good");                        Log.i("TAG","### current MyThread2 = " + Thread.currentThread().getName());                    }                }            };            Looper.loop();        }    }

以上就是两根子线程的代码
最后贴上调用代码

   @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        button = (Button) findViewById(R.id.button);        myThread = new MyThread();        myThread.start();        myThread2 = new MyThread2();        myThread2.start();    }

打印log如下:
打印的log
结论:
一根线程只能有一个looper对象,所以在子线程里面实例化Handler必需要跟Looper关联,所以我们只需要记住在子线程里面实例化Hanlder对象需要调用Looper.prepare()准备,并且最后无线循环的读取消息Looper.loop(),随后借助handler收发信息即可;

    -

run方法与start 区别


另外log里面也显示两根子线程确实是在子线程里面 ui线程在main线程里面,好我修改代码如下

    class MyThread extends Thread {        public Handler mHandler;        @Override        public void run() {            Log.i("TAG", "### current MyThread = " + Thread.currentThread().getName());        }    }   @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        Log.i("TAG", "### current Main = " + Thread.currentThread().getName());        // 调用方法修改为调用run 方法        myThread = new MyThread();        myThread.run();//        myThread = new MyThread();//        myThread.start();//        myThread2 = new MyThread2();//        myThread2.start();    }

我们运行一下看看log;

我在MyThread的run 方法里面打印了log,获取当前的线程名字,如上;
是不是很奇怪,明明就是在子线程里面为什么变成了main线程?

修改代码:

 myThread = new MyThread(); myThread.start();

打印log如下:

可以看到对比结果很明显,一个在子线程另外一个在main线程;

结论:
通过调用Thread类的start()方法来启动一个线程,这时此线程是处于就绪状态,并没有运行。
然后通过此Thread类调用方法run()来完成其运行操作的,这里方法run()称为线程体,它包含了要执行的这个线程的内容,
Run方法运行结束,此线程终止,而CPU再运行其它线程,

而如果直接用Run方法,这只是调用一个方法而已,程序中依然只有主线程,这一个线程,其程序执行路径还是只有一条,这样就没有达到写线程的目的。

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 生完宝宝腰疼怎么办 生完小孩后腰痛怎么办 生完小孩痔疮痛怎么办 生完孩子阴松弛怎么办 生完孩子乳房松弛怎么办 生完宝宝后腰痛怎么办 顺产的过程很疼怎么办 生完孩子想离婚怎么办 刨腹产后胃胀气怎么办 月子里宝宝涨肚怎么办 肠鸣放屁多便秘怎么办 趴着睡觉胃胀气怎么办 备孕三个月了还是没怀上怎么办 月子里喂奶腰疼怎么办 生完孩子子宫疼怎么办 记账凭证写错了怎么办 饥荒精神值为0怎么办 抓不住温暖我能怎么办 父亲打母亲我该怎么办 父亲对母亲家暴怎么办 摊上家暴的父亲怎么办 家暴警察不处理怎么办 父亲把母亲打了怎么办 u盘的文件打不开怎么办 头撞墙起包了怎么办 儿童头撞墙起包怎么办 头撞墙了鼓包了怎么办 北京65岁老年证怎么办 怎么办65岁免费乘车卡 5个月小孩晚上哭怎么办 婴儿要含奶头睡怎么办 我把输入法删了怎么办 头发干枯毛躁怎么办用什么洗发水 落枕后脖子歪了怎么办 睡觉睡得脖子疼怎么办? 婴儿脖子睡歪了怎么办 怀孕8个月肚皮痒怎么办 怀孕大阴唇肿了怎么办 孕妇肚皮撑的疼怎么办 我大阴唇特别长怎么办 切完洋葱辣眼睛怎么办