1.为什么学习多线程?
以后就可以将比较耗时的不稳定的工作封装为一个字线程,优化真个系统。
2、什么是进程 什么是线程。
(1)进程是程序或者任务执行的过程。
(2)持有资源(共享内存,共享文件)和线程。
(3)线程是系统中最小的执行单位, 同一个进程有多个线程,线程共享过程中的资源,
(4)一个cpu 在一个时间片段内只执行一个线程,以非常快的速度再切换。
三、如何创建一个线程?
(1)继承Thread 类
public class FirstThread extends Thread
需要重写run方法(主要放置你想要执行的代码逻辑)
线程启动 对象.start();
如果线程启动2遍,系统会报错
ps: 不要直接执行run方法。
(2)实现Runnable 接口
public class SecondRunnable implements Runnable {
重写run方法
new 一个thread类,将runnable的实现类的实例化对象当做参数传递进去
调用thread类的实例化对象的start方法,启动线程。
(3) 两种方式,那种更优?--第二种
原因:
1.java是单继承的,但是可以实现多个接口,用runnable的方式可以避免java 单继承带来的缺陷
2.thread可以只负责线程的相关操作,可以将业务逻辑这些内容分给runnable来做,各司其职,分工明确。
底层原理:thread也是一个实现了runnable接口的一个子类,只是拓展了一些关于线程的方法。
四.线程中常用的方法: Thread
run方法:入口方法,主要放置逻辑代码
start()方法:使线程开始执行(不一定会马上执行),java虚拟机调用该线程的run方法。
getName():返回该线程的名字。 主线程获取到的名字是main, 子线程获取到的默认名字是Thread-数字。
Thread.currentThread().getName();
sleep(毫秒值):线程休眠,参数是毫秒值,记得捕获异常。
currentThread():返回当前运行线程的引用(实例化对象)。
join():使其他线程等待当前线程终止。
yield(): 静态方法,当前运行线程释放处理器。
常见面试题:
sleep和yield 的区别:
sleep 使当前线程进入停滞状态,所以执行sleep的线程在指定时间内肯定不会执行;
yield使当前线程让出CPU资源,重回可执行状态,有可能刚进入可执行状态就立马执行。
五:线程的优先级
SetPriority 取值范围在1—10
默认是5 调用的时候放在线程start方法之前。
注意:设置线程优先级只是一个大概率事件。另外:不要将业务逻辑的核心交给优先级来处理。(不要指望他)
六:线程的生命周期
新建/开始 : new();
就绪:调用start()
运行:获取到执行权,进入到运行状态,失去执行权就进入就绪。
阻塞:在运行时遇到sleep方法,wait方法等进入阻塞状态。
死亡/结束:run方法执行完,Error或者Exception或者执行了stop方法()。
七.如何停止一个线程?
stop可以停止,但是是瞬间停止的,不能够将整体代码执行完毕后在停止。
终极方案:使用停止标志
interrupt()方法能够停止线程? 否
interrupt()方法不会中断一个正在运行的线程,他的作用是在线程受到阻塞时抛出一个中断信息,这样线程就可以退出阻塞状态,确切来说:调用了Object.wait(),Thread.join()和Sleep()
interrupt 不是终止线程,而是标志一个interrupted状态,调用一个会显示一个异常
八.守护线程。
什么是守护线程?常见的守护线程有那些?守护线程的特点,如何创建守护线程?注意那些内容?
线程按照功能分为用户线程和守护线程,用户线程运行在前台,执行的具体的操作。
守护线程运行在后台,为其他前台线程提供线程服务。
常见的守护线程有那些?
数据库连接池中的监测线程,JVM虚拟机启动后的监测线程,垃圾回收机制。
守护线程的特点:
一旦所有用户线程都结束,守护线程也随着jvm一起结束。
4
如何创建守护线程?
setDaemon(true);设置当前线程为守护线程
注意那些内容?
1.该语句必须在程序运行之前,start方法之前。
2.守护线程中产生的新的线程也是守护线程
3.不是所有任务都可以分配给守护线程来执行:读写操作或者逻辑运算。
九:线程安全问题
线程安全问题的解决方案:Oracle公司提供了线程同步机制来解决线程安全问题。
方式1:同步代码块
synchronized(锁对象){
需要同步的代码块
}
注意问题:
1.任何一个对象都可以作为锁对象
2.在同步代码块中调用sleep方法不能释放锁对象。
3.只有真正出现线程安全机制的时候再加同步代码块,否则不要加,因为效率变低
4.多线程操作的锁,对象必须是唯一共享的,否则无效
出现线程安全的原因:
1.存在两个或者多个线程对象,而且线程之间一定要有共享资源
2.要有多个语句操作来了共享资源
方法2:
同步函数:使用synchronized修饰一个函数
同步函数需要注意的地方:
1.如果是一个非静态的同步函数,锁对象是this对象
如果是静态的同步函数,锁对象是当前函数所属累的字节码文件(class)对象
2.同步函数的锁对象是固定的,不能由我们指定。
推荐使用:使用同步代码块
1、同步代码块的锁对象我么可以任意指定,同步函数的锁对象是固定的
2、同步代码块可以很方便的控制需要同步的代码块,但是同步函数一添加就必须是一个方法了。
十:出现死锁 的原因:
1、存在两个或者两个以上的线程
2、存在两个或者两个以上的共享资源
解决方案:没有好的方法,只能规避
十一: 线程的通讯: E:\myWorkspace\myWorkspace\JavaThread2\src\oneself\MsgDemo.java 例子
一个线程完成了自己的任务时,要通知另外一个线程去完成另外一个任务
案例:生产者与消费者 典型应用
Wait():等待,如果线程执行了wait方法,那么该线程会进入等待状态,直到另外一个线程去执行notify方法才被唤醒
notify():唤醒 唤醒线程池中等待的其中一个线程;
notifyAll(): 唤醒线程池中的所有等待的线程
wait() 与notify的注意事项:
1.wait() 方法和notify() 方法是属于Object方法的。
2、这两个方法必须要在同步代码块或者同步函数中才能调用。
3、这两个方法必须有锁对象调用
wait():一个线程如果执行了wait方法,那么该线程就会进入一个以锁对象为标志的线程池中进行等待。
notify(): 如果一个线程执行了Notify,那么就会唤醒以锁对象为标志的线程池中一个线程。
十二:
解决线程问题的方式:第二种 同步函数
* 使用synchronized修饰一个函数
* 同步函数需要注意的地方:
* 1、如果是一个非静态的同步函数,锁对象是this对象
* 如果是静态的同步函数,锁对象是当前函数所属类的字节码文件(class)对象
* 2、同步函数的锁对象是固定的,不能由我们指定
*
* 推荐使用: 使用同步代码块
* 1、同步代码块的锁对象我们可以任意指定,同步函数的锁对象是固定的。
* 2、同步代码块可以很方便的控制需要同步的代码块,但是同步函数一添加就必须是一个方法了。
十三:正则表达式 与js差不多
public static void main(String[] args) {
// TODO Auto-generated method stub
// 需要验证的字符串
String email ="yan_zhen-wei@163.com";
// 邮箱的校验规则
String regEx="[A-z0-9]+[A-z0-9_-]*\\@[A-z0-9]+\\.[A-z]+";
//编译正则表达式
Pattern pattern = Pattern.compile(regEx);
//把你对比的对象传过来
Matcher matcher =pattern.matcher(email);
boolean rs = matcher.matches();
System.out.println(rs);
}
数据库链接的监控线程
java中垃圾回收机制线程
以后就可以将比较耗时的不稳定的工作封装为一个字线程,优化真个系统。
2、什么是进程 什么是线程。
(1)进程是程序或者任务执行的过程。
(2)持有资源(共享内存,共享文件)和线程。
(3)线程是系统中最小的执行单位, 同一个进程有多个线程,线程共享过程中的资源,
(4)一个cpu 在一个时间片段内只执行一个线程,以非常快的速度再切换。
三、如何创建一个线程?
(1)继承Thread 类
public class FirstThread extends Thread
需要重写run方法(主要放置你想要执行的代码逻辑)
线程启动 对象.start();
如果线程启动2遍,系统会报错
ps: 不要直接执行run方法。
(2)实现Runnable 接口
public class SecondRunnable implements Runnable {
重写run方法
new 一个thread类,将runnable的实现类的实例化对象当做参数传递进去
调用thread类的实例化对象的start方法,启动线程。
(3) 两种方式,那种更优?--第二种
原因:
1.java是单继承的,但是可以实现多个接口,用runnable的方式可以避免java 单继承带来的缺陷
2.thread可以只负责线程的相关操作,可以将业务逻辑这些内容分给runnable来做,各司其职,分工明确。
底层原理:thread也是一个实现了runnable接口的一个子类,只是拓展了一些关于线程的方法。
四.线程中常用的方法: Thread
run方法:入口方法,主要放置逻辑代码
start()方法:使线程开始执行(不一定会马上执行),java虚拟机调用该线程的run方法。
getName():返回该线程的名字。 主线程获取到的名字是main, 子线程获取到的默认名字是Thread-数字。
Thread.currentThread().getName();
sleep(毫秒值):线程休眠,参数是毫秒值,记得捕获异常。
currentThread():返回当前运行线程的引用(实例化对象)。
join():使其他线程等待当前线程终止。
yield(): 静态方法,当前运行线程释放处理器。
常见面试题:
sleep和yield 的区别:
sleep 使当前线程进入停滞状态,所以执行sleep的线程在指定时间内肯定不会执行;
yield使当前线程让出CPU资源,重回可执行状态,有可能刚进入可执行状态就立马执行。
五:线程的优先级
SetPriority 取值范围在1—10
默认是5 调用的时候放在线程start方法之前。
注意:设置线程优先级只是一个大概率事件。另外:不要将业务逻辑的核心交给优先级来处理。(不要指望他)
六:线程的生命周期
新建/开始 : new();
就绪:调用start()
运行:获取到执行权,进入到运行状态,失去执行权就进入就绪。
阻塞:在运行时遇到sleep方法,wait方法等进入阻塞状态。
死亡/结束:run方法执行完,Error或者Exception或者执行了stop方法()。
七.如何停止一个线程?
stop可以停止,但是是瞬间停止的,不能够将整体代码执行完毕后在停止。
终极方案:使用停止标志
interrupt()方法能够停止线程? 否
interrupt()方法不会中断一个正在运行的线程,他的作用是在线程受到阻塞时抛出一个中断信息,这样线程就可以退出阻塞状态,确切来说:调用了Object.wait(),Thread.join()和Sleep()
interrupt 不是终止线程,而是标志一个interrupted状态,调用一个会显示一个异常
八.守护线程。
什么是守护线程?常见的守护线程有那些?守护线程的特点,如何创建守护线程?注意那些内容?
线程按照功能分为用户线程和守护线程,用户线程运行在前台,执行的具体的操作。
守护线程运行在后台,为其他前台线程提供线程服务。
常见的守护线程有那些?
数据库连接池中的监测线程,JVM虚拟机启动后的监测线程,垃圾回收机制。
守护线程的特点:
一旦所有用户线程都结束,守护线程也随着jvm一起结束。
4
如何创建守护线程?
setDaemon(true);设置当前线程为守护线程
注意那些内容?
1.该语句必须在程序运行之前,start方法之前。
2.守护线程中产生的新的线程也是守护线程
3.不是所有任务都可以分配给守护线程来执行:读写操作或者逻辑运算。
九:线程安全问题
线程安全问题的解决方案:Oracle公司提供了线程同步机制来解决线程安全问题。
方式1:同步代码块
synchronized(锁对象){
需要同步的代码块
}
注意问题:
1.任何一个对象都可以作为锁对象
2.在同步代码块中调用sleep方法不能释放锁对象。
3.只有真正出现线程安全机制的时候再加同步代码块,否则不要加,因为效率变低
4.多线程操作的锁,对象必须是唯一共享的,否则无效
出现线程安全的原因:
1.存在两个或者多个线程对象,而且线程之间一定要有共享资源
2.要有多个语句操作来了共享资源
方法2:
同步函数:使用synchronized修饰一个函数
同步函数需要注意的地方:
1.如果是一个非静态的同步函数,锁对象是this对象
如果是静态的同步函数,锁对象是当前函数所属累的字节码文件(class)对象
2.同步函数的锁对象是固定的,不能由我们指定。
推荐使用:使用同步代码块
1、同步代码块的锁对象我么可以任意指定,同步函数的锁对象是固定的
2、同步代码块可以很方便的控制需要同步的代码块,但是同步函数一添加就必须是一个方法了。
十:出现死锁 的原因:
1、存在两个或者两个以上的线程
2、存在两个或者两个以上的共享资源
解决方案:没有好的方法,只能规避
十一: 线程的通讯: E:\myWorkspace\myWorkspace\JavaThread2\src\oneself\MsgDemo.java 例子
一个线程完成了自己的任务时,要通知另外一个线程去完成另外一个任务
案例:生产者与消费者 典型应用
Wait():等待,如果线程执行了wait方法,那么该线程会进入等待状态,直到另外一个线程去执行notify方法才被唤醒
notify():唤醒 唤醒线程池中等待的其中一个线程;
notifyAll(): 唤醒线程池中的所有等待的线程
wait() 与notify的注意事项:
1.wait() 方法和notify() 方法是属于Object方法的。
2、这两个方法必须要在同步代码块或者同步函数中才能调用。
3、这两个方法必须有锁对象调用
wait():一个线程如果执行了wait方法,那么该线程就会进入一个以锁对象为标志的线程池中进行等待。
notify(): 如果一个线程执行了Notify,那么就会唤醒以锁对象为标志的线程池中一个线程。
十二:
解决线程问题的方式:第二种 同步函数
* 使用synchronized修饰一个函数
* 同步函数需要注意的地方:
* 1、如果是一个非静态的同步函数,锁对象是this对象
* 如果是静态的同步函数,锁对象是当前函数所属类的字节码文件(class)对象
* 2、同步函数的锁对象是固定的,不能由我们指定
*
* 推荐使用: 使用同步代码块
* 1、同步代码块的锁对象我们可以任意指定,同步函数的锁对象是固定的。
* 2、同步代码块可以很方便的控制需要同步的代码块,但是同步函数一添加就必须是一个方法了。
十三:正则表达式 与js差不多
public static void main(String[] args) {
// TODO Auto-generated method stub
// 需要验证的字符串
String email ="yan_zhen-wei@163.com";
// 邮箱的校验规则
String regEx="[A-z0-9]+[A-z0-9_-]*\\@[A-z0-9]+\\.[A-z]+";
//编译正则表达式
Pattern pattern = Pattern.compile(regEx);
//把你对比的对象传过来
Matcher matcher =pattern.matcher(email);
boolean rs = matcher.matches();
System.out.println(rs);
}
数据库链接的监控线程
java中垃圾回收机制线程