线程的相关定义
什么是进程?
进程是操作系统进行资源分配和调度的基本单位,是程序的执行实例。每个进程都有自己的内存空间和系统资源。
什么是线程?
线程是进程中的一个执行单元,是CPU调度的基本单位。一个进程可以包含多个线程,它们共享进程的内存空间和系统资源。
什么是多线程?
多线程是指在一个进程中同时运行多个线程,每个线程执行不同的任务。多线程可以提高程序的并发性能和响应速度。
什么是线程安全?
线程安全是指多个线程同时访问共享资源时,不会出现数据不一致或竞争条件等问题。线程安全的代码可以在多线程环境下正确运行。
并发和并行?
并发是指多个任务在同一时间段内交替执行,但并不是同时执行。并行是指多个任务在同一时刻同时执行。
线程的创建方式
继承Thread类
public class MyThread extends Thread {
@Override
public void run() {
System.out.println("Thread is running");
}
public static void main(String[] args) {
MyThread thread = new MyThread();
thread.start();
}
}
实现Runnable接口
public class MyRunnable implements Runnable {
@Override
public void run() {
System.out.println("Runnable is running");
}
public static void main(String[] args) {
MyRunnable runnable = new MyRunnable();
// Thread内使用静态代理机制调用传入的runnable的run方法
Thread thread = new Thread(runnable);
thread.start();
}
}
继承Thread类和实现Runnable接口的区别
- 继承Thread类不能继承其他类,实现Runnable接口可以继承其他类。
- 继承Thread类创建线程对象后,调用start()方法启动线程,调用run()方法只是普通方法调用,不会启动新线程。
线程终止
可以使用一个boolean变量来控制线程的循环,然后主进程将这个boolean变量设置为false,线程就会退出循环,从而终止线程。
class MyT extends Thread{
public boolean loop = true;
@Override
public void run() {
while(loop){
System.out.println("(>^ω^<)喵呜");
}
System.out.println("呜呜呜┭┮﹏┭┮,你居然关了偶,呜呜呜~");
}
}
public class TT {
public static void main(String[] args) {
MyT t = new MyT();
t.start();
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
System.out.println("oops");
}
t.loop = false;
}
}
线程常用方法
getName()
:获取线程名称。setName()
:设置线程名称。isAlive()
:判断线程是否存活。sleep()
:让当前线程睡眠指定毫秒数。join()
:等待调用线程终止。yield()
:让当前线程让出CPU资源,让其他线程执行,不一定能让成功。setPriority()
:设置线程优先级。interrupt()
:中断线程。
用户线程和守护线程
- 用户线程:也叫工作线程,当线程的任务执行完或通过通知方式结束。
- 守护线程:当进程中没有用户线程了,守护线程自动终止。例如,垃圾回收线程就是一个守护线程。
class MyT extends Thread{
public boolean loop = true;
@Override
public void run() {
while(loop) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
System.out.println("oops");
}
System.out.println("我一直~在你身后看着你~~~");
}
}
}
public class TT {
public static void main(String[] args) {
MyT t = new MyT();
// 设置为守护线程
t.setDaemon(true);
t.start();
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
System.out.println("oops");
}
// 工作线程结束,守护线程自动结束
System.out.println("主线程我要结束啦!妖魔鬼怪速速退去!妖魔鬼怪速速退去!");
}
}
线程的生命周期
![外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传](https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=image-3.png&pos_id=img-jRsrALdb-173781826411
9)
线程同步
什么是线程同步?
多个线程操作共享资源,如果多个线程同时操作共享资源,可能会出现数据不一致的情况,这时就需要线程同步,即让多个线程步调协同一致,有序地操作共享对象,即为线程同步。
线程同步的两种方式
同步代码块和同步方法。
- 同步代码块:
synchronized(对象)
{} - 同步方法:
public synchronized void method()
{} - 锁对象:任意对象都可以作为锁对象,但推荐使用共享资源作为锁对象,因为如果不是同一个对象,无法达到锁(同步)的效果。
- 死锁:两个线程互相等待对方释放资源,导致程序无法继续执行。
- 这里的synchronized使用的是互斥锁,即表示该对象任一时刻只能有一个线程访问,由此达到被所住的代码块或者方法只能由一个线程操作的目的。
- 同步非静态的方法的锁使用的对象(锁)可以是this,也可以是其他对象,但需要唯一,而同步静态方法的锁需要时类本身。
示例
public class TT {
public static void main(String[] args) {
Ticket t = new Ticket();
Thread t1 = new Thread(t);
Thread t2 = new Thread(t);
Thread t3 = new Thread(t);
t1.start();
t2.start();
t3.start();
}
}
class Ticket implements Runnable {
private int ticket = 100;
private Object obj = new Object();
@Override
public void run() {
while (true) {
// 同步代码块
synchronized (obj) {
if (ticket > 0) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "买票,票号:" + ticket);
ticket--;
} else {
break;
}
}
}
}
}
```![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/935abdf8e31442978b475ec0b5249207.png#pic_center)