黑马程序员技术交流社区
标题:
java基础(线程)
[打印本页]
作者:
lilongbin2016
时间:
2016-12-8 23:24
标题:
java基础(线程)
1、线程启动为什么要运用start()而不是run?
因为线程牵扯到操作系统的资源分配问题,所不能直接运用run方法,而需要使用start方法,这个方法实际上是去调用操作系统的方法。
2、线程的三种实现模式
继承thread类:单继承的局限
实现runnable接口:没有单继承的实现,可以实现数据共享
实现callable接口:在runnable基础上多了一个功能即可以返回值
线程的启动都得使用thread的start方法。
3、线程同步异步,可以使用代码块中加入synchronize修饰,或者在方法中加入synchronize
4、打断线程的睡眠必须是另一个线程,意思是一定要使用另一个线程对象去调用intercept方法。
5、多个线程访问同一个资源可能带来什么问题,并有什么附加的效果。
·多个线程访问同一个资源需要考虑同步问题。
·过多的同步可能对线程造成死锁。程序运行效率降低。
6、sleep 和 wait的区别
·sleep是thread的方法,睡眠时间到后会醒来。
·wait是object的方法,只用使用nodify或者nodifyAll方法才能唤醒。
对象调用wait后,对象会释放锁机制,等待该对象调用nodify方法后重新获取锁代表可以回到停顿的地方继续执行了,这个操作往往是因为资源不够,要等待另一个线程去创造一些资源的时候,等另一个线程创造好了资源(此时往往是在往共享数据中添加了资源,然后使用nodify方法,所以wait必须在synchronize中使用,否则就会抛出异常,这也很合理):常见案例:生产者和消费者。
sleep不会释放对象锁,因为sleep是线程的方法,无法去释放对象的锁(sleep只是短暂的睡眠,锁还是自己拿着,等醒了后就准备继续执行的)。
7、string stringBuffer stringBuilder
·string是不可改变的,StringBuffer是可以改变的。
·stringbuffer类有个反转,一个删除等特点性质的方法。
·stringbuffer和stringbuilder,前者线程安全的,后者非线程安全(异步的操作,性能更高)。
8、runtime类
·runtiem类是跟随一个进程的。构造方法是私有的,异味里面有一个静态的方法获取runtime来用
·GC:java的垃圾回收器,可以用runtime的gc方法手动回收垃圾,java也会自动回收未使用的对象。回收机制:永生代,年轻代,旧生代。
9、代码示例
Integer i1 = 40;
Integer i2 = 40;
Integer i3 = 0;
Integer i4 = new Integer(40);
Integer i5 = new Integer(40);
Integer i6 = new Integer(0);
System.out.println("i1=i2\t" + (i1 == i2));true:因为integer在java里跟string一样有维护一个常量池,这个常量池的大小是-127~128,当未使用new方法申明的基本封装类型时,是从常量池中获取数据的(当然这个是在上面的范围内),如果换成大于127的例如129就变成false了,因为超过常量池里的数后,就是通过new获取的,属于引用类型了。
System.out.println("i1=i2+i3\t" + (i1 == i2 + i3));true:java的数学计算是在栈中实现的,在栈中会进行拆箱操作,这个最后就是数学计算了,结果当然相等
System.out.println("i4=i5\t" + (i4 == i5)); false,指向的引用不同。
System.out.println("i4=i5+i6\t" + (i4 == i5 + i6)); true:java的数学计算是在栈中实现的,在栈中会进行拆箱操作,这个最后就是数学计算了,结果当然相等
10、java栈,堆
在java中,栈和堆都是存在于内存中的,栈中能存放的东西很少,因为栈的读取熟读要比堆块,所以栈中存放的东西自然就是一些对象的引用,和一些基本数据类型的存储(int,double等这样的)。堆中存放的是new出来的一些对象,还有常量池。
不管是普通类型的变量还是引用类型的变量(熟称实例),都可以在栈和堆中保存,只是普通类型的变量的值也是保存在栈中,而引用类型的变量只是把指向堆中的一个指针或者引用信息保存于栈中,而真正的值保存在堆中,所以引用类型的对象在栈和堆中都有保存信息。
11、栈和堆中对象生存周期
栈中存放的是对象的引用或者基本类型的值,当对象的引用或者基本类型的值是局部变量时,在方法使用完成java就会立刻释放栈中的
空间,而虽然是局部变量的引用但是其堆中对应的值确实要等java的垃圾回收机制制动回收,这个回收我们无法控制(可以使用Runtime.gc方法
但是也不是绝对的,当调用gc方法时,也只是告诉java虚拟机要去回收了,至于它到底回不回收是一回事。)
12、实例化和对象
实例化是保存在栈中的一个引用,对象是保存在堆中的,多个实例化可以指向同一个堆中的值。
13、java是在运行前jvm就为程序分配好地址的,运行时创建的对象会临时分配新的地址。如下代码测试(在运行时创建的字符串具有独立的内存地址,所以不引用自同一String对象):
string hello = "hello",lo="lo";
system.println.out(hello==("hel"+lo));
14、javavisualVM 一个查看内存分配的工具。
15、throws Throwable 是能同时处理exception和error的异常。
16、final,finally,finalize区别
final:定义不能被继承的父类,定义不能被子类覆写的方法,定义常量。
finally:是异常处理中进行异常处理的统一出口。
finalize:是object类的方法,是在对象被回收之前统一处理的一个方法即进行对象收尾操作(protected void finalize()throws Throwable)。
17、System类中 有一个gc方法,这个方法跟runntime.gc方法一样,gc方法永远只有一个(就是runntime中的gc,其他地方的gc都是调用而已。),所以System中的gc也是强制清空(注意这里是清空,不是回收。)
18、清空和回收
当把一个对象实例化赋值null后这时只是让java虚拟机回收该对象,等待清空状态,等到内存不足或者其他情况时在清空,而使用system.gc则是清空对象,gc方法是非常耗用cpu的,所以频繁使用会有适得其反的效果,这也是java开发中我们不手动去清空,而是使用java的垃圾回收机制自动去清空的原因。
19、System.currentTimeMillis:获取系统当前的时间,这个可以用来实现计算一个比较耗时的操作所用的时间。
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2