尚学堂java SE学习笔记(未完待续)

1、关于递归,一定要注意函数调用顺序!
图1尚学堂java SE学习笔记(未完待续)_第1张图片
如上图:在执行f(n-1)+f(n-2)的过程中,先执行f(n-1)一直到f(n-1)有返回值才执行f(n-2)。
2、
 图2

尚学堂java SE学习笔记(未完待续)_第2张图片
注意成员变量和局部变量的区别:关于成员变量见上图,但是在使用局部变量之前必须对之初始化!否则编译会报错(如果只是声明一个局部变量,而在以后的语句中不使用它的话就不会报错)!!
3、
   类是静态(代码)的概念,位于代码区;
   对象是new出来的,位于堆内存(可以动态分配),类的每个成员变量在不同的对象中都有不同的值(除了静态变量)而方法只有一份,方法执行的时候才占用内存。
   同一类的每个对象有不同的成员变量存储空间。
   同一类的每个对象共享该类的方法。
4、
  局部变量(包括基本变量和引用变量等)、形参等在stack(栈内存)中声明!!!
5、构造方法没有返回值!!!构造方法和类名一样,开头大写,其他方法都是小写。
6、类的书写习惯为:
图3

尚学堂java SE学习笔记(未完待续)_第3张图片
“}”单独占一行,属性和方法、方法和方法之间隔一行。

7、
  方法执行后,之前分配的空间(在栈中,因为方法中变量---局部变量,所占的空间都是栈空间)就立马消逝了。
8、
  类的方法只是一段代码(所有的对象共享),只有在调用的时候才会在内存各个部分分配空间。
9、
  非静态方法是针对每个对象进行调用
10、
  堆内存中,成员变量也可以指向堆内存中的其他堆。如下图:o是引用类型
图4

尚学堂java SE学习笔记(未完待续)_第4张图片
11、
  函数的返回值存在于栈内存的临时空间里。
12、
  this可以看做是一个变量,它的值是当前对象的引用。如下图:在堆内存中
图5

尚学堂java SE学习笔记(未完待续)_第5张图片
13、
图6

尚学堂java SE学习笔记(未完待续)_第6张图片
静态方法不再是针对某个对象调用,所以不能访问非静态成员(非静态成员和非静态方法只能针对某个对象调用!!!)
图8

尚学堂java SE学习笔记(未完待续)_第7张图片
在上图的代码中,main方法将执行完的内存分布如下:
图7

尚学堂java SE学习笔记(未完待续)_第8张图片
注意:static声明的静态成员变量,放在data seg(数据区)里,注意,字符串常量也放在data seg里。
14、
  把上述代码的static去掉的代码如下:
图9

尚学堂java SE学习笔记(未完待续)_第9张图片
图10

尚学堂java SE学习笔记(未完待续)_第10张图片
15、
   关于package import的总结:
class文件必须在正确的包目录下:例如在Cat类中,package com.a.b;则Cat.class必须位于com\a\b下!
必须class文件的最上层的父目录位于classpath下;
执行一个类需要写全包名:java com.sh.gczl.Cat;(配置环境变量或者进入到父目录)
关于打包:进入classpath下,jar -cvf test.jar *.*     //*表示所有的文件
16、
  关于继承:new一个子类实例之前先new父类。
17、
   重写:
    方法名称、返回值类型、参数全部一样;但是权限可以不一样~!!
    重写方法不能使用比被重写方法更严格的访问权限。
18、
    关于super:
图12

尚学堂java SE学习笔记(未完待续)_第11张图片
上图的main方法执行完前的内存为:
图11

尚学堂java SE学习笔记(未完待续)_第12张图片
 this,super都是引用。在new子类的时候先new一个父类,所以父类实例在子类实例里面。
图13

尚学堂java SE学习笔记(未完待续)_第13张图片
19、
  当成员变量的值是字符串时,则变量的引用指向“data seg”里的字符串。
20、
  java编译器按照classpath(“.;其他路径”--注意两者的顺序(谁在前就先按谁的路径下找类)!!)的顺序来找类进行编译。
21、
  Object的equals方法的默认实现是“x==y”;即比较引用。
  equals是单三形式,因为是对象和对象之间的比较。
图14


22、
  Dog d=new Dog();
 System.out.println(d);
默认会调用d.toString()方法,返回“类名@哈希码”。
哈希码是唯一表示对象的。
23、
图15

尚学堂java SE学习笔记(未完待续)_第14张图片
注意第二句话!!
24、
图16、17

尚学堂java SE学习笔记(未完待续)_第15张图片

尚学堂java SE学习笔记(未完待续)_第16张图片
25、
图18

尚学堂java SE学习笔记(未完待续)_第17张图片
26、
  多态的三个条件:要有继承、要有重写、父类引用指向子类对象
图21、22

尚学堂java SE学习笔记(未完待续)_第18张图片

尚学堂java SE学习笔记(未完待续)_第19张图片


图19、20

尚学堂java SE学习笔记(未完待续)_第20张图片

 

27、尚学堂java SE学习笔记(未完待续)_第21张图片
图23

尚学堂java SE学习笔记(未完待续)_第22张图片

如果extends了抽象类后不想实现其中的抽象方法的话,可以把自己也声明成抽象类,自己的方法也是抽象方法,然后把实现交给自己的子类就行了。

28、
图24

尚学堂java SE学习笔记(未完待续)_第23张图片
例(1)
public class Test{

public static void main(String[]a){
A a=new A();
a.i=9;
}

}

class A{
final int i=9;
}
编译报错,说明final的成员变量不 能被试图改变即使数值大小并没有改变。
例(2)
public class Test{

public static void main(String[] args){
A a=new A();
a.test(9);
}

}

class A{
final void test(final int i){
i=9;
}
}
编译报错:d:\Test.java:12: 不能指定最终参数 i
i=9;
说明:形参(局部变量)被final声明后不能被改变!

另:在类库中,很多类都是final的,例如:String、Math等。
说白了,被final声明后变成了只读的,不能被修改。

29、
  在c++中,允许多继承,但是继承的多个父类之间可能会有重名的属性,所以会出现错误。
  在java中只能允许单继承,这就避免了这种错误,虽然可以实现多个接口,但是接口里的属性是static的,所有的实例共享的。
图25

尚学堂java SE学习笔记(未完待续)_第24张图片
接口也有多态性

图26、27、28

尚学堂java SE学习笔记(未完待续)_第25张图片

尚学堂java SE学习笔记(未完待续)_第26张图片

尚学堂java SE学习笔记(未完待续)_第27张图片
分析以上的程序:接口也有多态性,如果一个类实现多个接口的话,用哪个接口声明(引用)就用哪个接口提供的方法(即别的接口提供的方法对其隐藏);

30、

 接口可以继承接口,类继承类。
31、
图29

尚学堂java SE学习笔记(未完待续)_第28张图片
32、
图30

尚学堂java SE学习笔记(未完待续)_第29张图片
图32

尚学堂java SE学习笔记(未完待续)_第30张图片
Error:是虚拟机出问题了,程序处理不了的;
Exception异常分为两种:RuntimeException和其他的,
                       其中RuntimeException可以不显式的用catch逮异常,因为很多异常比如数组溢出如果显式的逮的话很麻烦的;
                       其他的非RuntimeException必须显式的用catch去逮.
注意只要是RuntimeException就可以不逮,例如:
public class Test{

public static void main(String[] args){
A a=new A();
a.test(0);
}

}

class A{
void test( int i){
int j=4/i;
}
}

出错信息为:
图33

尚学堂java SE学习笔记(未完待续)_第31张图片
例如1:
public class Test{

public static void main(String[] args){
A a=new A();
a.test(0);
}

}

class A{
void test( int i)throws Exception{
int j=4/i;
}
}
出错信息为:
图34

尚学堂java SE学习笔记(未完待续)_第32张图片
例如2:
public class Test{

public static void main(String[] args){
A a=new A();
a.test(0);
}

}

class A{
void test( int i)throws RuntimeException{
int j=4/i;
}
}
出错信息为:
图35

尚学堂java SE学习笔记(未完待续)_第33张图片
因为算数异常是RuntimeException所以可以不处理,但是也可以显式的catch一下。
注意例如1和例如2的区别:例如1必须进行catch一下,否则无法编译。例如2中,打印的异常信息为两条,因为e.printStackTrace()包括出错的路径和调用的路径。


33、
图36、37、38

尚学堂java SE学习笔记(未完待续)_第34张图片

尚学堂java SE学习笔记(未完待续)_第35张图片

尚学堂java SE学习笔记(未完待续)_第36张图片

34、
  在类库中的方法中后边如果有throws的话,调用此方法的时候一般都是需要catch的异常。

35、
图39、40

尚学堂java SE学习笔记(未完待续)_第37张图片

尚学堂java SE学习笔记(未完待续)_第38张图片
如果extends RuntimeException的话,说明自定义的异常可以不做处理。

36、
  如果异常发生了,则后边的语句就不再执行了。
37、
图41

尚学堂java SE学习笔记(未完待续)_第39张图片

38、
图42

尚学堂java SE学习笔记(未完待续)_第40张图片
注意:java语言声明数组不能指定其长度,因为java分配在堆上边,例如:int a[4]是非法的;
在c语言中可以指定长度,在栈上分配4个小格来。
因为数组是引用类型,所以可以这样写int[] a=null;
数组的初始化和成员变量是一样的,例如下图:

图43

尚学堂java SE学习笔记(未完待续)_第41张图片
图44

尚学堂java SE学习笔记(未完待续)_第42张图片

39、
  如果元素为引用数据类型的话,内存变化如下:
当执行Date[] days;后变化如下图:
图45

尚学堂java SE学习笔记(未完待续)_第43张图片
当执行days=new Date[3];后变化如下图:
图46

尚学堂java SE学习笔记(未完待续)_第44张图片
当执行完for循环后如下:
图47

尚学堂java SE学习笔记(未完待续)_第45张图片

40、
图48、49、50

 尚学堂java SE学习笔记(未完待续)_第46张图片

尚学堂java SE学习笔记(未完待续)_第47张图片

尚学堂java SE学习笔记(未完待续)_第48张图片

41、
   在局部变量中,如果是基本类型的话,会在栈中开辟空间,如果想在堆中开辟空间的话,用包装类型就行了。

42、
  数组排序一:选择排序,即每次把第i位后边(包括第i位)最小的数放到第i位上,如下:
图51

尚学堂java SE学习笔记(未完待续)_第49张图片

但是这样效率并不高,因为每次找到比第i项小的数值的话就得和第i项做交换,而不是找到第i项以后最小的值才跟第i项交换,改进的方法如下:
图52

尚学堂java SE学习笔记(未完待续)_第50张图片
但是这样做的话,效率也不是最高的,因为每次外层循环都要在栈中重新开辟k、temp,循环结束后再弹出k、temp,改变以后如下:
图53

尚学堂java SE学习笔记(未完待续)_第51张图片
43、
  数组排序二:冒泡排序
图54、55

尚学堂java SE学习笔记(未完待续)_第52张图片

尚学堂java SE学习笔记(未完待续)_第53张图片

总结:冒泡和选择的巧计方法:冒泡是第二层循环体内数据的比较,选择是第一层数据和第二层数据的比较。

44、
  数三退出问题:有500个人拉手围成一圈,从第1个人开始数数,如果数到3就退出,下个人继续从1开始数数,求最后剩下的人是谁?
图56

尚学堂java SE学习笔记(未完待续)_第54张图片
上述问题如果用面向对象的话:
图57、58、59

尚学堂java SE学习笔记(未完待续)_第55张图片

尚学堂java SE学习笔记(未完待续)_第56张图片

尚学堂java SE学习笔记(未完待续)_第57张图片
45、
  二分查找
图60、61

尚学堂java SE学习笔记(未完待续)_第58张图片

尚学堂java SE学习笔记(未完待续)_第59张图片

46、
  二维数组
图62、63

尚学堂java SE学习笔记(未完待续)_第60张图片

尚学堂java SE学习笔记(未完待续)_第61张图片

47、
public class Test{

public static void main(String[] args){
int a[][]=new int[3][];
for(int i=0;i {
System.out.print(a[i]+",");

}
}

}
结果为:
图64


说明:一维里存放的是对二维的引用。
48、
public class Test{

public static void main(String[] args){
int a[][]={{1},{22,3}};
for(int i=0;i {
System.out.print(a[i]+",");

}
}

}
图65


说明:一维里存放的是对二维的引用。


49、
图66

尚学堂java SE学习笔记(未完待续)_第62张图片
如上图:一维里存的是对二维的引用,二维里存的是对字符串的引用。

50、
图67、68

尚学堂java SE学习笔记(未完待续)_第63张图片

尚学堂java SE学习笔记(未完待续)_第64张图片图67中,把数组s对字符串的引用copy了给数组sBak,这样sBak就会指向那些字符串了;
          把数组intArray对二维的引用copy给了数组intArrayBak。

51、
图69

尚学堂java SE学习笔记(未完待续)_第65张图片
字符串在data seg里开辟空间,字符串一旦声明则不可改变;
注意s1==s2,因为他们是对同一个字符串的引用。
52、
图70、71、72

尚学堂java SE学习笔记(未完待续)_第66张图片

尚学堂java SE学习笔记(未完待续)_第67张图片

尚学堂java SE学习笔记(未完待续)_第68张图片
注意:trim是去掉字符串的开头和结尾的空间,字符串中间的空间不去掉!!

53、
图73

尚学堂java SE学习笔记(未完待续)_第69张图片

图74、75

尚学堂java SE学习笔记(未完待续)_第70张图片

尚学堂java SE学习笔记(未完待续)_第71张图片

54、
图76 

尚学堂java SE学习笔记(未完待续)_第72张图片

55、
求字符串中大写字母、小写字母、非字母的个数
图77

尚学堂java SE学习笔记(未完待续)_第73张图片
也可以用另一种方法
图78

尚学堂java SE学习笔记(未完待续)_第74张图片
还有一种方法
图79

 

尚学堂java SE学习笔记(未完待续)_第75张图片
 

 

56、
求字符串“java”在字符串中出现的次数
图80、81

尚学堂java SE学习笔记(未完待续)_第76张图片

 

57、尚学堂java SE学习笔记(未完待续)_第77张图片
图82、83、84、85、86

尚学堂java SE学习笔记(未完待续)_第78张图片

尚学堂java SE学习笔记(未完待续)_第79张图片

 

 尚学堂java SE学习笔记(未完待续)_第80张图片

尚学堂java SE学习笔记(未完待续)_第81张图片

尚学堂java SE学习笔记(未完待续)_第82张图片

58、
 注意Integer.parseInt(s)和Integer.valueOf(s)的区别:前者返回int类型,后者Integer
 即:后者的返回值=new Integer(Integer.parseInt(s))
 

59、
图87 88 89 90

尚学堂java SE学习笔记(未完待续)_第83张图片

尚学堂java SE学习笔记(未完待续)_第84张图片

尚学堂java SE学习笔记(未完待续)_第85张图片

尚学堂java SE学习笔记(未完待续)_第86张图片

60、
图91

尚学堂java SE学习笔记(未完待续)_第87张图片
解答如下:
图92

尚学堂java SE学习笔记(未完待续)_第88张图片

61、
图93 94

尚学堂java SE学习笔记(未完待续)_第89张图片

62、
图95、96

尚学堂java SE学习笔记(未完待续)_第90张图片

尚学堂java SE学习笔记(未完待续)_第91张图片

注意:lastModified()方法返回值long类型的,因为计算机存的是从开始到现在的毫秒数。

63、
图97

尚学堂java SE学习笔记(未完待续)_第92张图片

注意:在linux里是“/”,但是在windows里“/”或者“\\”都行!!为什么是“\\”呢而不是“\”呢,因为“\\”是“\”的转移字符!!

把目录或文件按树形结构显示
图98

尚学堂java SE学习笔记(未完待续)_第93张图片

64、
枚举类型
图99     

尚学堂java SE学习笔记(未完待续)_第94张图片

65、
容器
图100

尚学堂java SE学习笔记(未完待续)_第95张图片
Set:无顺序,不能重复
List:有顺序,能重复
什么是重复呢:就是两个对象之间互相equals。
图101、102

尚学堂java SE学习笔记(未完待续)_第96张图片

尚学堂java SE学习笔记(未完待续)_第97张图片
注意:add的时候add()必须add对象,不能add基本数据类型的数据,因为栈里的数据可能随时会清空。
     上图中:System.out.println(c);会默认调用toString方法,而toString方法会调用里面每个数据的toString方法和“[]”。

66、
图103

尚学堂java SE学习笔记(未完待续)_第98张图片
如上图:
remove方法中,如果能在数据集里找到和它equals的实例,则remove,如果成功remove则返回true。
注意:new Integer(100).equals(new Integer(100))返回的是true,因为Integer重写了equals方法,如果里面的值相等的话就equals。

67、
图104

尚学堂java SE学习笔记(未完待续)_第99张图片
通过哈希码就很快找到对象,所以可以作为索引,所以重写equals方法的同时必须重写hasCode方法,因为两个对象equals的话,他们的hasCode也应该相等。那什么时候使用哈希码呢,当map的时候,找对象的时候按照索引(哈希码)找,而不必一个一个得比一下是不是equals。
图105

尚学堂java SE学习笔记(未完待续)_第100张图片

68、
图106

尚学堂java SE学习笔记(未完待续)_第101张图片
因为不同的容器存储方式不一样,所以遍历的方法不能统一,所以用不同容器来实例化Iterator接口。

图107

尚学堂java SE学习笔记(未完待续)_第102张图片
如上图:不能用c.remove(name)方法,因为Iterator使用的时候会把元素锁上,别的类用不了了。

69、
图108  109

尚学堂java SE学习笔记(未完待续)_第103张图片

尚学堂java SE学习笔记(未完待续)_第104张图片

70、
图110 111 112

尚学堂java SE学习笔记(未完待续)_第105张图片

尚学堂java SE学习笔记(未完待续)_第106张图片

尚学堂java SE学习笔记(未完待续)_第107张图片
如上图:retainAll是求交集

71、
图113

尚学堂java SE学习笔记(未完待续)_第108张图片
ArrayList是底层用数组实现的,LinkedList是用链表实现的。
Object set()方法返回的是修改前的元素。

72、
图114 115

尚学堂java SE学习笔记(未完待续)_第109张图片

尚学堂java SE学习笔记(未完待续)_第110张图片

73、
图116 图117 118

尚学堂java SE学习笔记(未完待续)_第111张图片

尚学堂java SE学习笔记(未完待续)_第112张图片
lastName是字符串类型,String覆写了compareTo方法。

74、
图119 120

尚学堂java SE学习笔记(未完待续)_第113张图片

尚学堂java SE学习笔记(未完待续)_第114张图片
TreeMap:二叉树,做索引。
上边的键值不能重复是比较的equals,但是挨个排的比较equals的话太慢,所以比较哈希码(int类型)就行了。所以我们要求重写equals方法必须重写hasCode方法,如果连个对象equals的话那么他们的哈希值也相等,如果比较对象的话直接比较哈希值就行了。
Object put(Object,object)返回的是被替换的value.虽然第二个参数要求引用类型,但是由于自动打包的话,直接往里传基本数据类型就行,比如:m.put("one",1);
 
int i=(Integer)m.get("one");注意:不能去掉Integer,因为get的返回值是Object类型,只有Integer才会自动拆箱。


图121 122

尚学堂java SE学习笔记(未完待续)_第115张图片

尚学堂java SE学习笔记(未完待续)_第116张图片

75、
图123

尚学堂java SE学习笔记(未完待续)_第117张图片
图124

尚学堂java SE学习笔记(未完待续)_第118张图片
如上图:第10、17行不用强制类型转换,这也是泛型的好处。
图125 126

尚学堂java SE学习笔记(未完待续)_第119张图片

所以在使用集合的时候最好使用泛型!!!

76、
图127 128 129 130 131 132

尚学堂java SE学习笔记(未完待续)_第120张图片

尚学堂java SE学习笔记(未完待续)_第121张图片

尚学堂java SE学习笔记(未完待续)_第122张图片尚学堂java SE学习笔记(未完待续)_第123张图片

 

尚学堂java SE学习笔记(未完待续)_第124张图片

尚学堂java SE学习笔记(未完待续)_第125张图片
如上图:如果直接close的话,如果现在正在从缓存区里写数据的话,就会造成缓冲区里的内容可能就无法取出了。所以先flush一下。

注意:write(byte[] b)和read(byte[] b)比write(int b)和read(int b)性能高,write(byte[] b)与read(byte[] b)是每次都是操作一个数组级别的数,而不用每操作一个字节就和硬盘打交道一次。

77、
字节流有时候肯能会造成读一个汉字只读一一个字节即只读一个汉字的一半,所以可用用字符流。
图133 134 135 136

尚学堂java SE学习笔记(未完待续)_第126张图片

尚学堂java SE学习笔记(未完待续)_第127张图片

尚学堂java SE学习笔记(未完待续)_第128张图片

尚学堂java SE学习笔记(未完待续)_第129张图片
Writer类的write(String string)方法自动调用String类的 toCharArray()方法,然后调用write(char[] c)。

78、
图137 138 139 140 141

尚学堂java SE学习笔记(未完待续)_第130张图片

尚学堂java SE学习笔记(未完待续)_第131张图片

尚学堂java SE学习笔记(未完待续)_第132张图片

尚学堂java SE学习笔记(未完待续)_第133张图片

尚学堂java SE学习笔记(未完待续)_第134张图片

注意:系统只能自动建文件,不能自动建目录。

79、
图142 143 144 145

尚学堂java SE学习笔记(未完待续)_第135张图片

尚学堂java SE学习笔记(未完待续)_第136张图片

尚学堂java SE学习笔记(未完待续)_第137张图片

尚学堂java SE学习笔记(未完待续)_第138张图片
大管道套小管道
注意:readLine是BufferedReader的方法,每次读一行,很方便啊

80、
图146 147

尚学堂java SE学习笔记(未完待续)_第139张图片

尚学堂java SE学习笔记(未完待续)_第140张图片
ISO8859_x/latin-x:包含了所有的西欧语言。

81、
图148

尚学堂java SE学习笔记(未完待续)_第141张图片
System.in是这样定义的:public static final InputStream in
外部在套层InputStreamReader可以防止汉字乱码,再套层BufferReader可以使用readLine方法很方便。
 
82、
图149 150

尚学堂java SE学习笔记(未完待续)_第142张图片

尚学堂java SE学习笔记(未完待续)_第143张图片
ByteArrayOutputStream baos=new ByteArrayOutputSteam()这行执行后以后会在内存开辟一个字节数组,并且有个管道指向这个区域。
注意:先进先读

83、
图151 152 153 154

尚学堂java SE学习笔记(未完待续)_第144张图片

尚学堂java SE学习笔记(未完待续)_第145张图片

尚学堂java SE学习笔记(未完待续)_第146张图片

尚学堂java SE学习笔记(未完待续)_第147张图片

84、
图155

尚学堂java SE学习笔记(未完待续)_第148张图片
如果想把对象以字节的方式保存起来,得实现Serializable接口(标记接口,无方法)
图156

尚学堂java SE学习笔记(未完待续)_第149张图片
transient(透明的)即:不会把它声明的变量序列化。
Serializable是标记接口,jdk会控制怎么序列化。如果想控制序列化的话可以实现Externalizable接口。public interface Externalizable extends Serializable它是Serializable的子接口,自己有2个方法:
readExternal(ObjectInput in)
writeExternal(ObjectOutput out)

85、
线程
public class Thread extends Object implements Runnable:Runable接口只定义了run方法。
图157 158 159

尚学堂java SE学习笔记(未完待续)_第150张图片

尚学堂java SE学习笔记(未完待续)_第151张图片

尚学堂java SE学习笔记(未完待续)_第152张图片
如上图:run方法和main方法里的for循环是同时执行的!!!
图160

尚学堂java SE学习笔记(未完待续)_第153张图片

最好使用接口:因为extends就写死了,因为只能单继承,就不能继承其他类了。

86、
图161 162 163

尚学堂java SE学习笔记(未完待续)_第154张图片

尚学堂java SE学习笔记(未完待续)_第155张图片

尚学堂java SE学习笔记(未完待续)_第156张图片
如上图:不能在run()后边加上throw InterruptException,因为覆写不能抛出和父类方法不同的异常。
上图中程序的结果是:每个一秒输出一次时间,10秒后被打断,程序结束。
在Thread类中还有一个stop方法:和interrupt会让本线程执行完(比如说处理异常)不同,stop会立即终止线程。

87、
图164

尚学堂java SE学习笔记(未完待续)_第157张图片
如上图:join()使得run方法执行完,main中的for才执行。

图165

尚学堂java SE学习笔记(未完待续)_第158张图片
yield会让出让其他线程执行
如上图:共启动2个线程,每次是10的倍数的时候就会让给其他线程执行。

图166

尚学堂java SE学习笔记(未完待续)_第159张图片
如上图:在没有加第五行的时候,两个线程执行行数差不多,因为cpu分配的时间片是一样的。但是如果加上第五行的,即第一个线程的优先级是正常+3,所以第一个线程执行很多了才会执行第二个线程的。

88、
正常的让线程结束应该如下图,而不是用interrupt和stop方法。
图167

尚学堂java SE学习笔记(未完待续)_第160张图片

89、
图170

尚学堂java SE学习笔记(未完待续)_第161张图片
图168

尚学堂java SE学习笔记(未完待续)_第162张图片
上图:结果是:t1,你是第2个使用timer的线程
              t2,你是第2个使用timer的线程
造成这种的现象的原因就是:在t1这个线程执行num++后,执行24行之前,t2执行了num++。
解决方法如下:把注释去掉,synchronized锁定当前对象(互斥锁),不会别的对象打断。还有一种方法如下图:
图169

尚学堂java SE学习笔记(未完待续)_第163张图片
执行此方法的过程中锁定当前对象。

90、
请模拟死锁:
图171 172

尚学堂java SE学习笔记(未完待续)_第164张图片

尚学堂java SE学习笔记(未完待续)_第165张图片
上图中:线程td1抱着01等着o2,线程td2抱着o2等着o1。

91、
一道面试题:下图,如果线程t锁住m1(里面有b),问另一个线程(main)是否能访问m2(里面有b)。
图173

尚学堂java SE学习笔记(未完待续)_第166张图片
那么下图中的结果是多少呢?
图174

尚学堂java SE学习笔记(未完待续)_第167张图片
结果是:b=2000
那么下边的程序呢:
图175

尚学堂java SE学习笔记(未完待续)_第168张图片
结果是:b=1000
        1000
也就是说:执行28行的时候,m2执行完把当前对象的锁释放掉,才能执行m1.

92、
生产者消费者问题
模拟如下:


图176 177 178 179

尚学堂java SE学习笔记(未完待续)_第169张图片

尚学堂java SE学习笔记(未完待续)_第170张图片

尚学堂java SE学习笔记(未完待续)_第171张图片

尚学堂java SE学习笔记(未完待续)_第172张图片


wait只能在synchronized的情况下使用。在线程阻塞时(即馒头吃完或者馒头生产的超过容量)使用wait。
notify和wait配套使用。如果是多个线程的话就必须用notifyAll了。
Object类中又一个wait(),在运行状态中,线程调用wait(),此时表示着线程将释放自己所有的锁标记,同时进入这个对象的等待队列。

等待队列的状态也是阻塞状态,只不过线程释放自己的锁标记。

Notify()

如果一个线程调用对象的notify(),就是通知对象等待队列的一个线程出列。进入锁池。如果使用notifyall()则通知等待队列中所有的线程出列。

 

那么sleep和wait有啥区别呢?
    首先理解什么是锁标记:每个对象除了属性和方法,都有一个monitor(互斥锁标记),用来将这个对象交给一个线程,只有拿到monitor的线程才能够访问这个对象。

 

一、sleep属于Thread类的方法,wait是Object的方法
二、在运行状态中,线程调用wait(),此时表示着线程将释放自己所有的锁标记,同时进入这个对象的等待队列。等待队列的状态也是阻塞状态,只不过线程释放自己的锁标记。
    而sleep是:
     sleep是线程被调用时,占着cpu去睡觉(但是占用索标记即占着对象),其他线程不能占用cpu(不能访问对象),os认为该线程正在工作,不会让出系统资源(对象),wait是进入等待池等待,让出系统资源(释放锁标记),其他线程可以占用cpu,一般wait不会加时间限制,因为如果wait的线程运行资源不够,再出来也没用,要等待其他线程调用notifyall方法唤醒等待池中的所有线程,才会在进入就绪序列等待os分配系统资源,

93、
网络编程不等于网站编程!!!
网络编程比如:qq,魔兽争霸等
网站编程:http html css等
图180

尚学堂java SE学习笔记(未完待续)_第173张图片
tcp比如输入密码,udp比如游戏,语音。
 
         

你可能感兴趣的:(java,SE)