标签:01 run Thread 方法 线程 多线程 异常 public
1、异常
1.1、异常概述
1.1.1、异常介绍和体系
- 异常就是程序可能出现了不正常的情况。程序在执行过程中,出现的非正常的情况,最终会导致JVM的非正常停止
- demo
- Error
- 严重问题,通过代码无法处理。比如:电源断了
- Exception
- 称为异常,它表示程序本身可以处理的问题
1.1.2、异常体系
- Exception编译时异常就是在编译的时候出现的异常
- RuntimeException运行时异常,就是在运行的时候出现的异常
- 虚拟机默认处理异常的方式
- 打印异常信息,终止程序
1.2、异常的处理方式
1.2.1、throws抛出异常
- throws格式
- 修饰符 返回值类型 方法名(参数) throws 异常类1,异常类2{}
- throws的作用
- 抛出异常,把异常抛给调用者处理
1.2.2、try...catch捕获异常
-
try...catch格式
-
try {
可能出现异常的代码
}catch(异常类名 变量名) {
异常的处理代码;
}
-
-
好处
- 可以让程序继续往下执行
1.2.3、finally代码块
-
格式
-
try {
可能出现异常的代码
}catch(异常类名 变量名) {
异常的处理代码;
}finally {
代码;(该代码一定会被执行)
}
-
1.2.4、Throwable的成员方法
- public String getMessage()返回此throwable的详细消息字符串
- public String toString()返回此可抛出的简短描述
- public void printStackTrace() 把异常的错误信息输出在控制台
1.2.5、注意事项
- 子类重写方法throws的异常要比父类方法throws的异常相同或更少
- 父类方法没有throws异常,子类方法只能try...catch处理
- PS:
- 这里的异常指的是编译异常
1.3、自定义异常
- 概念
- 就是为了让控制台的报错信息更加的见名知意
2、线程
2.1、多线程的好处
- 让程序可以"同时"做多件事情
2.2、并发和并行
- 并发
- 多个事件在同一时刻,同时执行
- 并行
- 多个事件在同一时刻,交替执行
2.3、进程和线程
- 进程概念
- 是一个正在运行的程序
- 线程概念
- 线程就是来执行代码的
- PS:线程是进程的执行单元
2.4、多线程运行原理
- CPU在多个线程间快速切换,造成"同时"运行的假象
- PS:本质上是交替执行,只是交替的很快,让用户感觉是同时执行
2.5、多线程的实现方式
2.5.1、继承Thread类
-
概述
- Thread类表示线程,通过Thread类启动多个线程
-
格式
-
// 1.定义类继承Thread类 public class MyThread extends Thread { // 2.重写run方法, 编写新线程要执行的代码 @Override public void run() { for (int i = 0; i < 20; i++) { System.out.println("run: " + i); } } }
// 3.创建子类对象
MyThread mt = new MyThread();// 4.调用start()方法
mt.start(); // 启动新线程,新的线程会自动执行mt.run()方法
-
-
Thread类启动线程步骤
-
- 定义类继承Thread类
-
- 重写run方法,编写新线程要执行的代码
-
- 创建子类对象
-
- 调用star()方法
-
-
注意
- 多线程程序随机并发执行
-
优缺点
- 优点
- 编码简单
- 缺点
- 线程类已经继承Thread,无法继承其他类,不利于扩展
- 优点
2.5.2、run()方法和start()方法的区别
- 为什么要重写run()方法
- 因为run()方法是用来封装被线程执行的代码
- run()方法和start()方法的区别
- run方法是继承线程封装执行的代码,直接调用,相当于普通方法的调用,并没有开启线程
- start方法是启动新线程,新线程自动调用run()方法
- 为什么要先启动子线程,再执行主线程任务
- 避免主线程任务提前执行完毕了
2.5.3、实现Runnable接口
-
Thread构造器
- public Thread(Runnable target)(其中之一)
- 根据Runnable对象创建线程对象
- public Thread(Runnable target)(其中之一)
-
格式
-
MyRunnble r = new MyRunnble(); Thread t = new Thread(r); t.start(); for (int i = 0; i < 20; i++) { System.out.println("main" + i); }
-
-
实现Runnable接口启动线程步骤
-
- 定义一个类MyRunnable实现Runnable接口
-
- 在MyRunnable类中重写run()方法
-
- 创建MyRunnable类的对象
-
- 创建Thread类的对象,把MyRunnable对象作为构造方法的参数
-
- 调用start()方法启动线程
-
-
优缺点
- 优点:可以继续继承类和实现接口,扩展性强
- 缺点:代码复杂一点,需要创建两个对象
2.5.4、匿名内部类创建线程
-
Demo
-
public class Demo06 { public static void main(String[] args) { new Thread(new Runnable() { @Override public void run() { while (true) { System.out.println("我是新线程!"); } } }).start(); while (true) { System.out.println("我是主线程!"); } } }
-
3、线程类的常见方法
3.1、获取和设置线程名称
-
方法
- String getName(): 获取线程的名字
- void setName(String name):设置线程的名字
- String getName(): 获取线程的名字
-
构造器
- Thread(String name) : 创建线程对象时,设置线程的名称
- Thread(Runnable r, String name) : 创建线程对象的时候,设置线程的名称
3.2、获得当前线程的对象
- 方法
- public static Thread currentThread():返回执行当前代码的线程对象
- 注意事项
- 此方法是Thread类的静态方法,可以直接使用Thread类调用
- 这个方法是被哪个线程执行的,就会得到哪个线程的对象
3.3、线程休眠
- 方法
- public static void sleep(long time):让线程休眠指定的事件,单位为毫秒
- 格式
- Thread.sleep(1000); // 休眠一秒
4、线程的安全问题
4.1、概念
- 多个线程同时操作共享资源导致数据错乱,称为线程安全问题
4.2、原因
- 多线程并发
- 同时访问共享资源
- 存在修改共享资源
4.3、多线程取钱业务案例
package Day08._02多线程.demo09多线程卖票;
class SaleTicket00 extends Thread{
private static int TicketCount = 100;
@Override
public void run() {
while (true) {
if (TicketCount > 0) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
}
TicketCount --;
System.out.println(getName() + "正在买票.........,剩余" + TicketCount + "张票");
}
else {
// System.out.println("票已经卖完了!");
break;
}
}
}
}
public class Demo09 {
public static void main(String[] args) {
SaleTicket00 buy1 = new SaleTicket00();
buy1.setName("buy1");
buy1.start();
SaleTicket00 buy2 = new SaleTicket00();
buy2.setName("buy2");
buy2.start();
SaleTicket00 buy3 = new SaleTicket00();
buy3.setName("buy3");
buy3.start();
}
}
4.4、线程同步思想
- 加锁
- 把共享资源进行上锁,每次只能一个线程进入访问,访问完毕以后解锁,然后其他线程才能进来
4.5、线程同步的实现方式
4.5.1、同步代码块
4.5.1.1、格式
- synchronized (锁对象) { 多条操作共享数据的代码}
4.5.1.2、作用
- 给代码块中的代码加锁,解决线程安全问题。
4.5.1.3、原理
- 每次只能一个线程获取锁进入,执行完毕以后自动解锁,其他线程才可以进来执行
4.5.1.4、要求
- 原则上:锁对象必须是同一个对象。
- 语法上:任意对象都可以作为锁,建议使用共享资源作为锁对象。
- 对于实例方法建 议使用this作为锁对象,此时this应该代表共享资源对象。
- 对于静态方法建议使用字节码类名.class对象作为锁对象。
4.5.2、同步方法
4.5.2.1、格式
- public synchronized void 方法名() { // 操作共享资源的代码}
4.5.2.2、作用
- 给方法加锁,解决线程安全问题。
4.5.2.3、同步方法原理
- 每次只能一个线程进入,执行完毕以后自动解锁,其他线程才可以进来执行。
4.5.2.4、同步方法底层原理
- 同步方法其实底层也是有隐式锁对象的,只是锁的范围是整个方法。
- 如果方法是实例方法:同步方法默认用this作为的锁对象。
- 如果方法是静态方法:同步方法默认用类名.class作为的锁对象。
4.5.3、Lock锁
4.5.3.1、API
4.5.3.2、格式
在成员变量位置: private final Lock lock = new ReentrantLock();
try {
lock.lock()
操作共享资源的代码
} finally {
lock.unlock();
}
标签:01,run,Thread,方法,线程,多线程,异常,public 来源: https://www.cnblogs.com/OnlyOnYourself-lzw/p/16471451.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。