集合就是可延长的数组
本地回环地址: 127.0.0.1 本机名: localhost
端口号 有效端口: 0--65535, 其中0-1024端口被系统使用或者保留
传输协议有 tcp 。 udp 两个、
while和 if 的区别:::::
if 只做判断,判断一次之后,便不会再回来了
while 的话,循环,直到结果为false,才跳出来
try catch块中的 finally 存放的 一般都是释放资源的动作
栈内存空间小于 堆内存空间
栈 凡是局部变量都 存储在栈内存里面
main函数执行时,会在栈内存中开辟空间,主函数调用方法时也会为方法开辟空间
当方法执行完毕时,会自动释放内存空间
堆 使用关键字 new 出来的实体 都存储在 堆 内存里
堆里面的每一个实体都有 一个内存地址值
堆内存的变量都有默认初始化值
当堆内存的实体 没有任何引用使用它的话 ,不会被立刻回收。会不定时被垃圾回收器回收
选择排序 ,冒泡排序 , 效率是比较低的
排序中最快的排序方式是 希尔排序 ::因为它在栈内存临时存储
普通的数组元素位置交换是发生在 堆内存 中的,而堆内存中换位置比较消耗资源
当类中要操作的引用数据类型不确定的时候 ,
需要定义泛型来解决
高级for循环的极限性, ,,,必须有被遍历的目标,且不能对被遍历collection进行操作
迭代器除了遍历,还可以进行remove操作,,如果用ListIterator,还可以在遍历中增删改查
高级for循环 可以对 数组 , 对list集合, 对set,集合记性遍历
但是在遍历数组时, 还是建议用传统for,。因为传统for可以顶定义角标
静态方法不可以访问 类上定义的泛型。如果静态方法类型不确定,可以将泛型定义在方法上
方法上定义泛型 如 public <Q> void method(Q q)
静态方法定义泛型如 public static <T> void method(T t)
泛型定义在 返回类型符的 前面 , 修饰符的后面
泛型限定 如 public static void print(ArraList<? extends Person> a1){} 这个是上限定
ArraList<? extends Person>
public static void print(ArraList<? super Person> a1){} 这个是下限定
api 就是 application programming interface
hasptable 底层是哈希表数据结构 ,不可以存入null键和null值,该集合线程是同步的 ,
并且效率低 , 出现在jdk1 1.0版本
haspmap 底层是哈希表数据结构, 可以存入null键和null值, 该集合线程是不同步的,
并且效率高 , 出现在jdk 1.2版本
treemap 底层是二叉树的数据结构, 线程不同步, 可以用于给map集合中的键进行排序
因为线程不同步的原因, 所以性能上要比 同步的优越一些 , 但是要自己管理线程上的同步问题
基本上集合跟它的父类是不同写法的,都是不同步的, 如 vector就是线程不同步。它是list的子类
set集合跟 map集合很像。 其实 set 底层使用的就是 map集合
map 集合 如果想key 和 value 都取出的话 必须用 到 keyset ,和entryset
因为map集合是 没有 迭代器 , 而 set 集合 具备迭代器
构造块:直接在类中定义且没有加static关键字的代码块称为{} 构造代码块。
构造代码块在创建对象时被调用,每次创建对象都会被调用,
并且构造代码块的执行次序优先于类构造函数。
1。 静态代码块不能存在于任何方法体内。2
2. 静态代码块 不能 直接访问类的实例变量和实例方法,需要通过类的实例对象来访问。
final 被final修饰的类 不能被继承, 即没有子类。
被final 修饰的方法 不能被子类 重写,但可以重载多个final修饰的方法
而且 如果方法中再被 private修饰的话,直接导致子类不能继承此方法
一个类要被 使用 必须经过装载,链接 ,初始化这样的过程 , 由java虚拟机完成
单例设计模式 : 有三大类 :1.懒汉式设计模式 ,就是在第一次调用自己时,实例化
存在线程安全问题,有三种解决方式
2.饿汉式设计模式,在类加载时就创建了实例,
不存在线程安全问题
3.登记式设计模式, 登记式单例实际上维护了一组单例类的实例,
将这些实例存放在一个Map(登记薄)中,对于已经登记过的实例,
则从Map直接返回,对于没有登记的,则先登记,然后返回。
其实内部实现还是用的饿汉式单例
反射是基于框架的 , 想要看懂框架必须 看得懂 反射, 框架一般来说是基于配置文件的。
反射第一步,就是加载类, Class.forName("类的全路径名"); 得到返回相关联的class对象
private私有的东西能被外界访问吗?
不可以,只能被类的内部访问 但是 反射可以做到这一点 Constructo.setAccessible(true);
取map集合内的数据有两种方式
方式一,用 map.keySet();
方式二,用map.entrySet();
Set set = map.entrySet();
Iterator iter = set.iterator();
while(iter.hasNext()){
Map.Entry entry = (Entry) it.next();
String key = (String) entry.getKey();
String value = (value) entry.getValue();
}
增强for循环只能用于读取数据 , 不能不能不能用于 修改数据
基本数据类型的数组 它整个就是一个特殊的对象,
其他数据类型的数组 , 它就是一个对象数组
基本数据类型:使用时需要赋具体值,判断时使用“==”号
引用数据类型:使用时可以赋null,判断时使用equals方法
==比较的是两个变量的内容 ,如果是引用类型的话,他们的栈内容就是引用的地址值
char[]是字符数组 byte[]是字节数组
java基本数据类型就 8 种 , 四类八种
第一类: 整型 byte,short,int,long
第二类: 浮点型 float,double
第三类; 逻辑型 boolean
第四类; 字符型 char
除了这些基本数据类型之外, 其他都是引用数据类型 ,
引用数据类型也有 三大种类 , array数组 String字符串 其他
引用数据类型:类、接口类型、数组类型、枚举类型、注解类型;
基本数据类型也有引用类型,byte , Byte ,像这样等等类似
HashSet ,HashMap数据结构是哈希表,线程是不同步的。
注意:::如果想线程同步安全,又想用map的话,使用ConcurrentHashMap代替
保证元素的唯一性原理,判断元素的hashcode值是否相同。
如果相同,还会继续判断equals方法,是否为true。
TreeSet使用二叉树原理,可以对Set集合中的元素进行排序、
使用自然排序方式,但如果键为自定义类,则必须通过实现comparable
的compareTo进行排序判断。另一种方式就是自定义一个comparator实现类
比较器new TreeSet( myComparator);
statement 和PreparedStatement 的区别;
1.PreparedStatement 是statement 的子类;
2.PreparedStatement 可以防止sql注入问题,通过对用户的输入进行转义
3.PreparedStatement 具有预编译功能,可以减轻数据库压力
什么时候使用 map 集合呢????、、???
当发现有 映射关系 时, 可以选择 map 集合
因为吗map 集合中存放的就是映射关系。
String 和 StringBuilder 和 StringBuffer 的区别:
1. String 类 因为有final 修饰符, String 内部成员是不可以修改的,而其他两者可以修改
String 的本质就是 char [ ] + 操作
共同点: StringBuilder 和 StringBuffer 实现了相同的接口 abstractStringBuilder
2。因为 StringBuffer 对方法加了同步锁,所以线程是安全的,StringBuilder线程不安全
3。如果程序不是多线程的,那么使用StringBuilder 效率高于 StringBuffer
实际中应用 StringBuffer 的比较多
抽象类 和 接口 的区别:
语法层面上的区别:
1,抽象类可以提供各种成员方法的实现细节,而接口只能存在public abstract方法
2,抽象类的成员变量可以是各种类型,而接口的只能pubilic static final类型
3,抽象类可以包含静态代码块和静态方法,而接口不能
4.,一个类只能继承一个抽象类,但是可以实现多个接口
设计层面上的区别:
1,抽象类是对事物的抽象, 接口是对行为的抽象。
如飞机和鸟,他们都是各种飞机和各种鸟的类的统称,而飞则是一种行为,无法抽象成类
2,抽象类是模板设计模式,而接口是辐射式设计模式
如修改抽象类等于修改他的子类,是个模板,而每个实现接口的类,都有自己对这个行为的解释
辐射式设计模式,一旦标准改变,所有的从属也要相应改变。
javabean 的属性 不由 它的 字段 的多少来决定的
是由它的 get或set 方法来决定的
别忘了object类 也有一个getClass() 方法
mid = ( max + min )>>1; // ./2
Connections
把数组变成 list集合有什么好处? Arrays.aslist(String[] xx );
可以使用集合的思想 和 方法 来操作数组中的元素,因为数组方法功能比较少
注意 : 将数组变成集合,不可以使用集合的 增删方法
因为数组的长度是固定的
注意: 如果数组中的元素都是对象,也就是非基本数据类型,那么编程集合时,
数组中的元素 就直接转成 集合的元素
如果数组中的元素就是 基本数据类型,那么会将该数组作为集合中的元素存在
为什么要把 集合 变成 数组
为了限定对元素的操作
当把 集合 变成 数组 是要注意 使用以上方法 arrayList.toArray(new String[arrayList.size()]);
当注定类型的数组长度 小于 集合的size
Properties 是HashTable的子类, 也就是map集合的一个子类对象
可以通过map 的方法去除该集合中的元素
该集合存储的都是String 没有泛型定义
System.getProperties();可以获取系统的配置信息
一个类 最多 只能 继承一个类
一个类可以 实现多个 接口
多线程问题 写多线程时, ,,,必须小心安全问题
如果先要多线程共享一个实例变量, 就要把实例变量定义为 静态变量
应为静态变量只能 有一个实例 ,即 多个改类的对象 共享一个实例变量
如果一个线程创建了 并且 运行过一次 start();方法了
就不能再 调用start方法; 否则会抛出异常 正在运行的线程,不能调用该线程start()
虽然实现多线程有两种方法 , 继承Thread 或者 实现Runnable
但是真正创建线程的只有Thread类 或其后代才可以
那么问题来了实现方式和继承方式有什么区别呢?????
1.实现方式的好处 ,避免了 单继承的 局限性,所有建议使用实现的方式
2.继承thread 的线程代码存放在thread 子类run方法中
而实现runnable , 线程代码存放在接口的子类的 run方法中
多线程在操作共享数据时 ,特别要留意 执行共享数据的语句, 很容易引发线程安全问题
同步有两种方式,一种是同步代码块,另一种是同步函数。。同步静态函数,,,,,
这个对象就相当于一个锁
同步的前提: sychronized(对象){ }
1.不须要有多线程 } 同步函数的锁是 this
2、必须是多个线程使用同一个锁 public sychronized void show(){
} 同步静态函数用锁是该类的字节码文件对象 类名.class
必须保证同步中只能有一个线程在运行 public static sychronized void show(){
} 因为静态进内存时,内存中没有本类对象
好处: 解决了多线程的安全问题
弊端: 多个线程需要判断锁, 较为消耗资源
同步锁 有死锁 :::就是因为存在 同步锁的嵌套 , 如下
线程一 sychronized(Locka){ 线程二 sychronized(LockB){
sychronized(LockB){ sychronized(Locka){
} }
} }
线程间的通讯:::::
其实就是多个线程在操作同一个资源, ,但是操作的动作不同
线程间的通讯,,,多使用等待唤醒机制 wait(); notify(); 还有一个notifyAll();
线程运行时,内存中会建立一个线程池。 等待的线程都存放在线程池中
notify();唤醒的是谁,通常唤醒第一个被等待的。
注意注意:::::: wait(); notify(); 还有一个notifyAll();
因为要对持有 监视器(锁) 的线程操作,而只有同步才具有锁
为什么以上这些方法要定义在object类中呢????????
因为这些方法在操作同步中线程时,都必须要标识它们所操作线程只有锁
只有同一个 锁 上的被wait等待线程,才能被同一个锁notify唤醒
注意::不可以对不同锁中的线程唤醒。
也就是说 等待和唤醒,必须是同一个锁
而锁可以是任意对象,所以可以被任意对象调用的方法定义在object中
在jdk1.5后 Lock对象代替了 sychronized代码块和sychronized对象
Condition对象 代替了 监视器(锁)的: wait(); notify(); 还有一个notifyAll();
出现这些对象的一大好处是。,Lock 可以 new 出多个 Condition对象
意味着一个锁可以 分开wait 分开唤醒, 而不需要通过notifyAll(); 唤醒全部线程
两段需要同步的代码,共享一个锁 ,却可以唤醒对象,而自己wait();
如何停止线程????????????
只有一种方法,,,就是让run方法结束掉,线程通常都是循环的,
只要控制住循环,,,,就能让run 方法结束,也就是线程结束
通常是做一个标记位,,,flag;
特殊情况:::::::::::
当线程处于冻结状态,,就不会读取到循环的标记位,线程就不会结束
当没有指定的方式让冻结的线程恢复到运行状态时,需要对冻结状态进行清除
强制让线程恢复到运行状态中来,这样就可以操作标记位 让线程结束
thread类提供了一个这样的方法,,,,thread.interrupt();
会抛出异常。这时应该在catch代码块中 改变flag
守护线程或者用户线程 是什么意思呢??? 其实可以理解为 ::后台线程
后台线程的特点是,,开启后,和前台线程共同抢劫cpu的资源
开启运行都没什么区别,区别是 结束时,
当所有的前台线程结束时,,,所有的后台线程会自动结束,你在我故我在
为什么称之为守护线程呢,,,,,就是守护前台的线程,守护对象没了,自己也没了
thread.join();??????????????????????????????????????????????j
当A线程执行到了B线程的 threadB.join();时,A就会等待。等B线程都执行完,A才会执行
设计模式::
单例 ,,工厂,,观察者模式,,装饰设计模式,,适配器,,组合模式
组合模式::部分和整体 在外面面用起来 具有 一致性
java 对象 存放在 ~~~ 堆 ~~~~~内存空间里
服务是不能直接new出来 new出来的服务只能是普通的对象
服务的对象 是被系统(框架)new 出来的
面向对象::::
在开发过程的一种 方法论
字符输出流 需要读取完数据后 需要刷新才能输出也就是
write();
flush();
但是 字节流 ,读取完数据,,可以不需要刷新缓冲数据
write();就可以了
其实字符流底层
用的也是 字节流 的缓冲区
file:::
createrNewFile();方法,可以在指定位置创建文件夹,如果该文件已经存在,
则不创建。和输出流不一样,输出流对象一建立文件,且文件存在,就会覆盖
如果通过反射 调用 对象里面的方法的话:
如果方法的参数是 可变参数,,或者 参数是 数组[]的话,
就要在 你想要传的数组参数外面再包裹一个数组object[],
另一种方法是,,把数组 强行转化为 object对象
这是因为jdk1.5新出的可以数组,需要向下兼容导致的
本地回环地址: 127.0.0.1 本机名: localhost
端口号 有效端口: 0--65535, 其中0-1024端口被系统使用或者保留
传输协议有 tcp 。 udp 两个、
while和 if 的区别:::::
if 只做判断,判断一次之后,便不会再回来了
while 的话,循环,直到结果为false,才跳出来
try catch块中的 finally 存放的 一般都是释放资源的动作
栈内存空间小于 堆内存空间
栈 凡是局部变量都 存储在栈内存里面
main函数执行时,会在栈内存中开辟空间,主函数调用方法时也会为方法开辟空间
当方法执行完毕时,会自动释放内存空间
堆 使用关键字 new 出来的实体 都存储在 堆 内存里
堆里面的每一个实体都有 一个内存地址值
堆内存的变量都有默认初始化值
当堆内存的实体 没有任何引用使用它的话 ,不会被立刻回收。会不定时被垃圾回收器回收
选择排序 ,冒泡排序 , 效率是比较低的
排序中最快的排序方式是 希尔排序 ::因为它在栈内存临时存储
普通的数组元素位置交换是发生在 堆内存 中的,而堆内存中换位置比较消耗资源
当类中要操作的引用数据类型不确定的时候 ,
需要定义泛型来解决
高级for循环的极限性, ,,,必须有被遍历的目标,且不能对被遍历collection进行操作
迭代器除了遍历,还可以进行remove操作,,如果用ListIterator,还可以在遍历中增删改查
高级for循环 可以对 数组 , 对list集合, 对set,集合记性遍历
但是在遍历数组时, 还是建议用传统for,。因为传统for可以顶定义角标
静态方法不可以访问 类上定义的泛型。如果静态方法类型不确定,可以将泛型定义在方法上
方法上定义泛型 如 public <Q> void method(Q q)
静态方法定义泛型如 public static <T> void method(T t)
泛型定义在 返回类型符的 前面 , 修饰符的后面
泛型限定 如 public static void print(ArraList<? extends Person> a1){} 这个是上限定
ArraList<? extends Person>
public static void print(ArraList<? super Person> a1){} 这个是下限定
api 就是 application programming interface
hasptable 底层是哈希表数据结构 ,不可以存入null键和null值,该集合线程是同步的 ,
并且效率低 , 出现在jdk1 1.0版本
haspmap 底层是哈希表数据结构, 可以存入null键和null值, 该集合线程是不同步的,
并且效率高 , 出现在jdk 1.2版本
treemap 底层是二叉树的数据结构, 线程不同步, 可以用于给map集合中的键进行排序
因为线程不同步的原因, 所以性能上要比 同步的优越一些 , 但是要自己管理线程上的同步问题
基本上集合跟它的父类是不同写法的,都是不同步的, 如 vector就是线程不同步。它是list的子类
set集合跟 map集合很像。 其实 set 底层使用的就是 map集合
map 集合 如果想key 和 value 都取出的话 必须用 到 keyset ,和entryset
因为map集合是 没有 迭代器 , 而 set 集合 具备迭代器
构造块:直接在类中定义且没有加static关键字的代码块称为{} 构造代码块。
构造代码块在创建对象时被调用,每次创建对象都会被调用,
并且构造代码块的执行次序优先于类构造函数。
1。 静态代码块不能存在于任何方法体内。2
2. 静态代码块 不能 直接访问类的实例变量和实例方法,需要通过类的实例对象来访问。
final 被final修饰的类 不能被继承, 即没有子类。
被final 修饰的方法 不能被子类 重写,但可以重载多个final修饰的方法
而且 如果方法中再被 private修饰的话,直接导致子类不能继承此方法
一个类要被 使用 必须经过装载,链接 ,初始化这样的过程 , 由java虚拟机完成
单例设计模式 : 有三大类 :1.懒汉式设计模式 ,就是在第一次调用自己时,实例化
存在线程安全问题,有三种解决方式
2.饿汉式设计模式,在类加载时就创建了实例,
不存在线程安全问题
3.登记式设计模式, 登记式单例实际上维护了一组单例类的实例,
将这些实例存放在一个Map(登记薄)中,对于已经登记过的实例,
则从Map直接返回,对于没有登记的,则先登记,然后返回。
其实内部实现还是用的饿汉式单例
反射是基于框架的 , 想要看懂框架必须 看得懂 反射, 框架一般来说是基于配置文件的。
反射第一步,就是加载类, Class.forName("类的全路径名"); 得到返回相关联的class对象
private私有的东西能被外界访问吗?
不可以,只能被类的内部访问 但是 反射可以做到这一点 Constructo.setAccessible(true);
取map集合内的数据有两种方式
方式一,用 map.keySet();
方式二,用map.entrySet();
Set set = map.entrySet();
Iterator iter = set.iterator();
while(iter.hasNext()){
Map.Entry entry = (Entry) it.next();
String key = (String) entry.getKey();
String value = (value) entry.getValue();
}
增强for循环只能用于读取数据 , 不能不能不能用于 修改数据
基本数据类型的数组 它整个就是一个特殊的对象,
其他数据类型的数组 , 它就是一个对象数组
基本数据类型:使用时需要赋具体值,判断时使用“==”号
引用数据类型:使用时可以赋null,判断时使用equals方法
==比较的是两个变量的内容 ,如果是引用类型的话,他们的栈内容就是引用的地址值
char[]是字符数组 byte[]是字节数组
java基本数据类型就 8 种 , 四类八种
第一类: 整型 byte,short,int,long
第二类: 浮点型 float,double
第三类; 逻辑型 boolean
第四类; 字符型 char
除了这些基本数据类型之外, 其他都是引用数据类型 ,
引用数据类型也有 三大种类 , array数组 String字符串 其他
引用数据类型:类、接口类型、数组类型、枚举类型、注解类型;
基本数据类型也有引用类型,byte , Byte ,像这样等等类似
HashSet ,HashMap数据结构是哈希表,线程是不同步的。
注意:::如果想线程同步安全,又想用map的话,使用ConcurrentHashMap代替
保证元素的唯一性原理,判断元素的hashcode值是否相同。
如果相同,还会继续判断equals方法,是否为true。
TreeSet使用二叉树原理,可以对Set集合中的元素进行排序、
使用自然排序方式,但如果键为自定义类,则必须通过实现comparable
的compareTo进行排序判断。另一种方式就是自定义一个comparator实现类
比较器new TreeSet( myComparator);
statement 和PreparedStatement 的区别;
1.PreparedStatement 是statement 的子类;
2.PreparedStatement 可以防止sql注入问题,通过对用户的输入进行转义
3.PreparedStatement 具有预编译功能,可以减轻数据库压力
什么时候使用 map 集合呢????、、???
当发现有 映射关系 时, 可以选择 map 集合
因为吗map 集合中存放的就是映射关系。
String 和 StringBuilder 和 StringBuffer 的区别:
1. String 类 因为有final 修饰符, String 内部成员是不可以修改的,而其他两者可以修改
String 的本质就是 char [ ] + 操作
共同点: StringBuilder 和 StringBuffer 实现了相同的接口 abstractStringBuilder
2。因为 StringBuffer 对方法加了同步锁,所以线程是安全的,StringBuilder线程不安全
3。如果程序不是多线程的,那么使用StringBuilder 效率高于 StringBuffer
实际中应用 StringBuffer 的比较多
抽象类 和 接口 的区别:
语法层面上的区别:
1,抽象类可以提供各种成员方法的实现细节,而接口只能存在public abstract方法
2,抽象类的成员变量可以是各种类型,而接口的只能pubilic static final类型
3,抽象类可以包含静态代码块和静态方法,而接口不能
4.,一个类只能继承一个抽象类,但是可以实现多个接口
设计层面上的区别:
1,抽象类是对事物的抽象, 接口是对行为的抽象。
如飞机和鸟,他们都是各种飞机和各种鸟的类的统称,而飞则是一种行为,无法抽象成类
2,抽象类是模板设计模式,而接口是辐射式设计模式
如修改抽象类等于修改他的子类,是个模板,而每个实现接口的类,都有自己对这个行为的解释
辐射式设计模式,一旦标准改变,所有的从属也要相应改变。
javabean 的属性 不由 它的 字段 的多少来决定的
是由它的 get或set 方法来决定的
别忘了object类 也有一个getClass() 方法
mid = ( max + min )>>1; // ./2
Connections
把数组变成 list集合有什么好处? Arrays.aslist(String[] xx );
可以使用集合的思想 和 方法 来操作数组中的元素,因为数组方法功能比较少
注意 : 将数组变成集合,不可以使用集合的 增删方法
因为数组的长度是固定的
注意: 如果数组中的元素都是对象,也就是非基本数据类型,那么编程集合时,
数组中的元素 就直接转成 集合的元素
如果数组中的元素就是 基本数据类型,那么会将该数组作为集合中的元素存在
为什么要把 集合 变成 数组
为了限定对元素的操作
当把 集合 变成 数组 是要注意 使用以上方法 arrayList.toArray(new String[arrayList.size()]);
当注定类型的数组长度 小于 集合的size
Properties 是HashTable的子类, 也就是map集合的一个子类对象
可以通过map 的方法去除该集合中的元素
该集合存储的都是String 没有泛型定义
System.getProperties();可以获取系统的配置信息
一个类 最多 只能 继承一个类
一个类可以 实现多个 接口
多线程问题 写多线程时, ,,,必须小心安全问题
如果先要多线程共享一个实例变量, 就要把实例变量定义为 静态变量
应为静态变量只能 有一个实例 ,即 多个改类的对象 共享一个实例变量
如果一个线程创建了 并且 运行过一次 start();方法了
就不能再 调用start方法; 否则会抛出异常 正在运行的线程,不能调用该线程start()
虽然实现多线程有两种方法 , 继承Thread 或者 实现Runnable
但是真正创建线程的只有Thread类 或其后代才可以
那么问题来了实现方式和继承方式有什么区别呢?????
1.实现方式的好处 ,避免了 单继承的 局限性,所有建议使用实现的方式
2.继承thread 的线程代码存放在thread 子类run方法中
而实现runnable , 线程代码存放在接口的子类的 run方法中
多线程在操作共享数据时 ,特别要留意 执行共享数据的语句, 很容易引发线程安全问题
同步有两种方式,一种是同步代码块,另一种是同步函数。。同步静态函数,,,,,
这个对象就相当于一个锁
同步的前提: sychronized(对象){ }
1.不须要有多线程 } 同步函数的锁是 this
2、必须是多个线程使用同一个锁 public sychronized void show(){
} 同步静态函数用锁是该类的字节码文件对象 类名.class
必须保证同步中只能有一个线程在运行 public static sychronized void show(){
} 因为静态进内存时,内存中没有本类对象
好处: 解决了多线程的安全问题
弊端: 多个线程需要判断锁, 较为消耗资源
同步锁 有死锁 :::就是因为存在 同步锁的嵌套 , 如下
线程一 sychronized(Locka){ 线程二 sychronized(LockB){
sychronized(LockB){ sychronized(Locka){
} }
} }
线程间的通讯:::::
其实就是多个线程在操作同一个资源, ,但是操作的动作不同
线程间的通讯,,,多使用等待唤醒机制 wait(); notify(); 还有一个notifyAll();
线程运行时,内存中会建立一个线程池。 等待的线程都存放在线程池中
notify();唤醒的是谁,通常唤醒第一个被等待的。
注意注意:::::: wait(); notify(); 还有一个notifyAll();
因为要对持有 监视器(锁) 的线程操作,而只有同步才具有锁
为什么以上这些方法要定义在object类中呢????????
因为这些方法在操作同步中线程时,都必须要标识它们所操作线程只有锁
只有同一个 锁 上的被wait等待线程,才能被同一个锁notify唤醒
注意::不可以对不同锁中的线程唤醒。
也就是说 等待和唤醒,必须是同一个锁
而锁可以是任意对象,所以可以被任意对象调用的方法定义在object中
在jdk1.5后 Lock对象代替了 sychronized代码块和sychronized对象
Condition对象 代替了 监视器(锁)的: wait(); notify(); 还有一个notifyAll();
出现这些对象的一大好处是。,Lock 可以 new 出多个 Condition对象
意味着一个锁可以 分开wait 分开唤醒, 而不需要通过notifyAll(); 唤醒全部线程
两段需要同步的代码,共享一个锁 ,却可以唤醒对象,而自己wait();
如何停止线程????????????
只有一种方法,,,就是让run方法结束掉,线程通常都是循环的,
只要控制住循环,,,,就能让run 方法结束,也就是线程结束
通常是做一个标记位,,,flag;
特殊情况:::::::::::
当线程处于冻结状态,,就不会读取到循环的标记位,线程就不会结束
当没有指定的方式让冻结的线程恢复到运行状态时,需要对冻结状态进行清除
强制让线程恢复到运行状态中来,这样就可以操作标记位 让线程结束
thread类提供了一个这样的方法,,,,thread.interrupt();
会抛出异常。这时应该在catch代码块中 改变flag
守护线程或者用户线程 是什么意思呢??? 其实可以理解为 ::后台线程
后台线程的特点是,,开启后,和前台线程共同抢劫cpu的资源
开启运行都没什么区别,区别是 结束时,
当所有的前台线程结束时,,,所有的后台线程会自动结束,你在我故我在
为什么称之为守护线程呢,,,,,就是守护前台的线程,守护对象没了,自己也没了
thread.join();??????????????????????????????????????????????j
当A线程执行到了B线程的 threadB.join();时,A就会等待。等B线程都执行完,A才会执行
设计模式::
单例 ,,工厂,,观察者模式,,装饰设计模式,,适配器,,组合模式
组合模式::部分和整体 在外面面用起来 具有 一致性
java 对象 存放在 ~~~ 堆 ~~~~~内存空间里
服务是不能直接new出来 new出来的服务只能是普通的对象
服务的对象 是被系统(框架)new 出来的
面向对象::::
在开发过程的一种 方法论
字符输出流 需要读取完数据后 需要刷新才能输出也就是
write();
flush();
但是 字节流 ,读取完数据,,可以不需要刷新缓冲数据
write();就可以了
其实字符流底层
用的也是 字节流 的缓冲区
file:::
createrNewFile();方法,可以在指定位置创建文件夹,如果该文件已经存在,
则不创建。和输出流不一样,输出流对象一建立文件,且文件存在,就会覆盖
如果通过反射 调用 对象里面的方法的话:
如果方法的参数是 可变参数,,或者 参数是 数组[]的话,
就要在 你想要传的数组参数外面再包裹一个数组object[],
另一种方法是,,把数组 强行转化为 object对象
这是因为jdk1.5新出的可以数组,需要向下兼容导致的