(一)线程与进程
- 进程:正在运行的一个程序(qq ide 浏览器)
系统会为这个进程分配独立的内存资源 - 线程:具体执行任务的最小单位
- 线程与进程的关系:一个进程至少拥有一个线程(主线程 运行起来就执行的线程)
- 线程的特点:
1.线程之间共享内存资源(进程申请的)
2.线程之间可以通信(数据传递)
3.每一个进程都有自己的生命周期
4.线程的生命周期:也就是这个线程的状态 -
线程的状态:
如图所示:
NEW:新建状态
RUNNABLE:就绪状态 只要抢到时间片就可以运行
BLOCKED:阻塞状态 sleep wait都可能阻塞一个线程
WAITING:等待状态
TIME_WAITING
TERMINATED: 终止状态
展示图1.png
(二)多线程
- 子线程:在主线程进行的同时为了不妨碍主线程的工作而创建
- 为什么要创建子线程
如果在主线程中存在有比较耗时的操作:下载视频 上传文件 数据处理,这些都会阻塞主线程,后面的任务必须等待这些任务执行完毕之后才能执行,用户体验比较差 -
如何创建一个子线程
如图示方法:
展示图.png - 方式一:写一个类继承于Thread 实现run方法
步骤一:定义一个类继承Thread并且实现run方法
class TestThread extends Thread{
//实现run方法
//方法里面就是具体需要执行的代码
@Override
public void run() {
String name = Thread.currentThread().getName();
for (int i = 0; i <=100; i++) {
System.out.println(name + " "+i);
if(this!=MyClass.testThread1) {
if (i == 10) {
try {
MyClass.testThread1.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
super.run();
}
}
步骤二:创建对象 调用Thread方法实现功能
String name = Thread.currentThread().getName();
System.out.println(name);
//创建Thread的对象
TestThread testThread = new TestThread();
//设置子线程的名称
testThread.setName("子线程1");
//开启方法
testThread.start();
-
实际效果:
首先获取了线程的名字
改变了子线程的名字
实现了线程的功能
效果图.png - Thread里面的具体方法:
- join:让当前这个线程阻塞 等join的线程执行完毕在执行
1.setName:设置线程名称
2.getName:获取线程名称
3.currThread:获取当前运行的线程对象
4.start:开启任务 - 方式二:实现runable接口 实现run方法
步骤一:创建任务 创建类实现Runnable接口
class PXDthread implements Runnable{
public void run() {
for (int i = 0; i <=100; i++) {
System.out.println(Thread.currentThread().getName());
}
}
}
步骤二:使用Thread为这个任务分配线程
方式一:直接创建对象调用方法
PXDthread pt = new PXDthread();
//使用Tread操作 这个任务
Thread t = new Thread(pt);
t.setName("子线程2");
t.start();
方式二:使用匿名类
Thread t =new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i <=100; i++) {
System.out.println(Thread.currentThread().getName());
}
}
});
t.setName("子线程1");
t.start();
方式三:创建线程的同时直接开启线程任务不需要操作线程对象本身
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i <=100; i++) {
System.out.println(Thread.currentThread().getName());
}
}
}).start();
方式四:使用lambda表达式 不建议:阅读性太差
new Thread(()->{ for (int i = 0; i <=100; i++) {
System.out.println(Thread.currentThread().getName());
}
}).start();
(三)线程安全
- 方法:synchronized Lock 加锁解锁
-
synchronized
方式一:同步代码块
模板:synchronized(监听器/对象/锁){
//需要同步的代码
}
实际运用:
synchronized (obj){
//需要同步的代码
}
if(NUM>0) {
System.out.println(name + "出票" + NUM);
NUM--
}else{
break;
}
- 作用:可以保证在进行代码块的时候不会被其他线程所打断
方式二:同步方法
模板:public synchronized void test()<=>synchronized(this){test();}
注意事项:必须确保对个对象调用的同步方法时操作的是同一个对象,若不是同一对象还是使用同步代码块方法
(四)今日小结:
每一天依旧是一样的辛劳,但是还算是有收获的,每天看似很小的进步,慢慢积累就会有很大提高了,不知不觉已经过了这么多天了。既然选择了这条道路也就只能一步步坚持走下去了。