实战篇三

又是线程对象和线程,相信大多数人都和我一样会觉得枯燥,诗剑总是想挖空心思的让我们区分线程和线程对象,其实,从表面上区分非常简单,我们创建的Thread的实例就是所谓的线程对象,实例调用了start方法之后启动的整个执行过程就是线程,理解起来其实也并没有那么多难度。

但是,静下心来想想,如果我们能够更好的区分这两个概念,在程序中应该能够处理的更加得心应手,关于这两个概念的重要性,我们目前这种编程水平还难以感受到,可能随着规模的扩大,这种概念的掌握程度可能会带给我们更加清晰的思路。所以我们还是要花点时间消化一下这节的内容。

说实话,看了这部分内容之后,我对线程和线程对象的区别并没有太深的印象,只知道了线程对象是一个不能序列化的对象,因为它包含了主机的运行环境相关的信息,线程调度机制,安全机制等特定于当前运行环境的信息,不同的计算机有不同的运行环境。但是,对另一块的内容却有了更加清楚的认识,那就是关于序列化的知识。

在学习中,我们已经学会了使用序列化和反序列化功能的方法,首先需要让需要序列化的类实现Serializable接口,这样我们就可以序列化和反序列化这个类,使用到的是ObjectInputStream和ObjectOutputStream这两个类中的readObject和writeObject方法。
现在我们仔细回忆下,我们序列化的对象很多时候都是自己定义的类的对象,它们之所以能顺利的序列化,那是因为我们创建的对象中只有一些数据,它们和当前的运行环境并没有关系,只是一些数据的集合,能够完全反应出对象的全貌,所以序列化和反序列化都是作用于这些数据,不会造成不同的结果。而那些存储有运行环境信息的特殊对象,我们是无法对其实现序列化的。

Java中创建线程对象有继承和实现接口两种方法,文中分析了实现接口方式的作用:

(1) 关于其中所说的回调,我并不是很明白,不知道是不是C语言中的内容,如果有同学比较清楚地希望能够帮我解释下,按照我自己的理解就是在接口中定义了一个抽象的run方法,通过实现类实现该方法,将实现类对象作为参数返回给Thread对象,最终调用的run方法虽然是实现类中的,但是已经在接口中定义了,相当于调用接口对象的run方法。

(2) 实现接口的类的对象中,我们只是存放了需要处理的数据以及处理数据的方法,全部通过run方法来实现,在创建Thread对象时,才将Runnable对象中的数据加上线程需要的环境信息成为真正的线程对象,这样在编程时我们便将数据和环境分离开来,在Runnable接口的实现类中处理处理数据即可。

(3) 最重要的作用:我们之前都知道实现接口的方式可以实现数据共享,因为Runnable接口的实现类中用于存放和处理数据,多个Thread对象可以共用一个Runnable对象,所以多个线程就实现了数据的共享。其实,继承方法也可以实现数据共享,但是要复杂一些。下面两种方式都可以实现数据共享:

class T implements Runnable{
Object o;
public void run(){
for(int i = 0; i<10;i++){
System.out.println(o);
}
}
}

共享的数据就是o和run方法的主体(即整个实现类对象),共享数据在本类中直接定义。

class T extends Thread{
Object o;
public T(Object o){
this.o =o;
}
public void run(){
for(int i = 0; i<10;i++){
System.out.println(o);
}
}
}

共享的数据是o和run方法主体,但是o需要通过参数从外部传入。

这样我们应该更加清楚实现接口和继承两种方式的使用区别了,希望大家在使用时注意选择。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值