------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
进程:
这个正在进行的程序。
线程:
是进程中的内容。是程序中的控制单元,执行路径(情景)
是进程中的一个独立控制单元。
线程控制进行的单元。
进程中至少有一个线程负责Java执行而且这个线程运行代码存在于main方法中,该线程称为主线程。
多线程存在的意义:
提高效率
如何在自定义代码中自定义一个线程?
通过API查找Java已提供对线程这类事物描述就是thread类
创建的第一种方式就是i继承thread类
步骤:1.定义类继承thread
2.复写。run()目的:将自定义代码存在run()中让线程运行
3.调用线程start()(作用:1.启动线程2.调用run())
例子:
运行结果每次都不同的原因:
因为多线程都在获取CPU执行权,CPU执行到谁,谁就运行在某一时刻自能有一个程序在运行(多核除外),CPU在做快速切换动作看上去同时在运行,我们可以把多线程运行的行为看做是互相抢夺CPU执行权。
多线程特性:
随机性(执行多长时间由cpu说了算)
为什么覆盖run();
Thread描述线程,该类定义了一个功能,用于存运行的方法就是run()。
获取当前线程对象:
Thread.currentThread();
第二种方式
步骤:1.定义:类名 implements Runnable
2.覆盖run()
3.通过Thread建立线程对象
4.将Runnable子类对象作为实参传给Thread类的构造函数
5.调用Thread类start方法开启线程并调用Runnable子类中的run
例子:
实现和继承关系及区别:
实现方式:避免了单继承的局限性,在定义线程时,用实现方式。
继承方式:线程代码存放在Thread子类run方法中
实现方式:线程代码存放在Runnable接口子类run方法中
多线程必须注意安全问题
问题原因:
当多条语句操作同一个线程共享数据时,其中一个线程只执行了一部分语句,另一个线程进入导致共享数据错误。
解决办法:
让 一个线程执行完前,其他线程不能执行。
解决方式:
同步代码块
同步的前提:
1.必须要哟2个或以上线程。
2.必须是多个线程使用同一个锁。
必须保证同步中只有一个线程运行
弊端:
多个线程都需要判断锁,消耗资源。
如何找问题:
1.明确哪些代码是多线程运行的
2.明确哪些是共享数据
3.明确多线程运行代码中哪些语句是操作共享数据的
同步:
1,、同步代码块
例子:
2、同步函数
例子:
同步函数用的锁是:函数被对象调用时,函数有个所属对象引用就是this,所以用的锁是this
同步函数被静态修饰时,锁不是this是字节码文件对象。就是:类名.class
死锁:同步中嵌套同步
例子:
线程间通信:就是多个线程在操作同一个资源但动作不同
例子:
等待唤醒机制:
wait()、notify()、用于同步中
因为要对持有监视器的线程操作,因同步才有锁。
为什么操作线程的方法定义Object类中?
因为操作同步线程时,必须标识所操作线程持有的锁,只有一锁上的被等待线程可被同一notify()唤醒,不可被不同所唤醒,即等待唤醒是同一锁,锁是任意对象,所以wait在Object中。
JDK1.5使用lock和condition显示锁机制
stop():停止线程,方法已经过时,如何停止线程?只能到run结束。开启多线程运行代码常是循环,至于控制循环让run()结束就可以了。
特殊情况:
当线程处于冻结状况,就不会读标记,线程就不会结束,当没有指定方式让冻结线程回复到运行状态时,要冻结清除强制线程运行,这样可以操作标记结束。Thread提供interrupt中断线程,冻结状态清除。
t1.setDaemon(true);守护线程(后台线程)启动前使用。前台线程结束则后台自动结束。
join():
(临时加入执行,申请加入)抢夺CPU执行权(主线程会冻结)
yield():
临时释放执行权
线程的应用例子:
String类型:
String是字符串的类类型,用于描述字符串事物,字符串是一个特殊的对象。
特点:初始化后不能改变。
字符串:常量池中存在的数据
例子:
String s = ”abc“;s是类类型变量,”abc“是对象。
Sting s1 = ”abc“与String s2 = new Sring(”abc“)区别:
s1在内存中有一个对象,s2在内存中右两个对象,
String复写了equals():用于判断内容是否一致。
常见操作:
1.获取:
1.1int length();字符串中包含的字符数,就是长度
1.2char charAt(index);获取位置上的字符
1.3int indexOf(int ch)
int indexOf(int ch,int fromindex);字符位置
1.4int indexOf(String str);
int indexOf(String str,int fromindex);字符串的位置
1.5lastIndexOf(String str);反向索引字符位置
2.判断
2.1Boolean contains(str);是否含某一子串
2.2boolean isEmpty();是否其中有内容
2.3boolean startsWith(str);是否以指定内容开头
2.4boolean endsWith(str);是否以指定内容结尾。
2.5boolean equals(str);判断字符串内容是否相同
2.6boolean equalsIgnoraCase();判断内容是否相同并忽略大小写
3.转换
3.1String valueOf(char[],offset,count)
valueOf(char[],offset,count);字符数组转成字符串
3.2char[] toCharArray();字符串转成数组
3.3将3.1char变成byte;字节数组转成字符串
3.4byte[] getBytes();字符串转成字节数组
3.5Static String valueOf(基本型);将基本数据类型转为字符串
特殊:字节数组和字符串在抓换过程中,是可以指定编码表的。
4.替换:
String replace(oldchar,newchar);
5.切割:
String[] splite(regex);
6.子串:
String subString(begin,end);含头不含尾
String subString (begin);
7.转换
7.1String toUpperCase();字符转成大写
String tolowerCase();字符转成小写
7.2String trim();取代哦字符串两端的空格
7.3int compareTo();对两个字符串进行自然顺序比较
例子:
StringBuffer
是一个容器,长度可变,可操作多种数据类型。通过toString变成字符串,可以用于对字符串的修改,是字符串缓冲区。
常用方法:
1.存储:
StringBuffer append();
StringBuffer insert(index,key);插入
2.删除
StringBuffer delete(start,end);
StringBuffer deleteCharAt(index);
3.获取
char charAt(index);
int indexOf(str);
int length();
String subString(start,end);
4.修改
StringBuffer replace(start,end,key);
void setCharAt(index,key);
5反转
StringBuffer reverse();
6.将缓冲区中指定数据存储到指定数组中
void getChars(int srcBegin,int srcEnd,char[] dst,int dstBegin)
StringBuilder:线程不同步,功能和StringBuffer一样
StringBuffer:线程同步
升级三个因素:1.提高效率2.简化书写3.提高安全性
基本数据类型包装类
最常见作用:
基本数据类型和字符串类型之间转换
基本数据类型转成字符串:
1.基本数据类型+”“;
2.基本数据类型.图String(值);
字符串转成数据类型
xxx a = Xxx.parseXxx();
常用方法:
Integer.toBinaryString(数);转成二进制
Integer.toHexString(数);转成八进制
Integer.toOctalString(数);转十六进制
Integer.parseInt(”数“,进制);