线程常用方法--用户线程/守护线程
1.用户线程:也叫工作线程 ,当线程的任务执行完成 或通知方式结束
2.守护线程:一般是为工作线程服务的,当所有的用户线程结束守护线程自动结束
3:常见守护线程:垃圾回收机制
以下为守护线程案例
public class thread3 { public static void main(String[] args) throws InterruptedException { Daemon daemon = new Daemon(); //如果希望main结束以后子线程自动结束,那么直接设置为守护线程即可,记住一定要在start之前设置 daemon.setDaemon(true); daemon.start(); for (int i = 1; i <= 10 ; i++) { System.out.println("德丽莎在工作....."); Thread.sleep(100); } } } class Daemon extends Thread { @Override public void run(){ for (int i = 0; i < 10; i++) { try { Thread.sleep(500); } catch (InterruptedException e) { throw new RuntimeException(e); } System.out.println("阿波卡利斯在工作..." + i); } } }
线程的生命周期
线程生命周期图
Synchronized/线程同步机制
1.在多线程编程,一些敏感数据不允许被多个线程同时访问,此时就使用同步访问技术,保证数据在任何同一时刻,最多有一个线程访问,以保证数据完整性.
2.也可以这样理解:线程同步,即当有一个线程在对内存进行操作时,其他线程都不可以对该内存地址操作,直到该线程完成操作.
同步的具体方法
一个代码块要被同步的意思是,这段代码的操作,每时刻只能有一个线程访问
就好像上厕所排队,一个人上厕所的时候会锁门,其他人不能进去.上完以后开锁下一个人进去
以下例子是将该方法设置为同步方法
public class thread2 { public static void main(String[] args) throws InterruptedException { ticket Ticket1 = new ticket(); ticket Ticket2 = new ticket(); Thread thread1 = new Thread(Ticket2); Thread thread2 = new Thread(Ticket2); thread1.start(); thread2.start(); } } class ticket implements Runnable{ private int num = 20;//让多个线程共享这个num,static修饰 @Override public synchronized void run(){ while(num>0) { try { Thread.sleep(100); } catch (InterruptedException e) { throw new RuntimeException(e); } System.out.println(Thread.currentThread().getName()+ "还剩 "+(--num)+"张"); } } }
分析同步原理
互斥锁(Mutex)是一种同步机制,用于保护共享资源,避免多个线程同时访问和修改同一个资源,导致数据不一致或者出现其他异常的情况。
在Java中,互斥锁被称为synchronized关键字。当一个线程获得了对象的锁,其他线程就无法访问该对象的同步代码块或者同步方法,只能等待当前线程释放锁,才能继续执行同步代码块或者同步方法。
互斥锁的实现基于内置锁(Intrinsic Lock),也称为监视锁(Monitor Lock),它在Java虚拟机中是基于对象的,每个对象都有且只有一个内置锁。如果线程A获得了对象的锁,那么线程B就无法获得该对象的锁,只能等待线程A释放锁之后,才能获得锁。
尽量选择同步代码块,不要大范围同步
使用synchronized关键字修饰的代码块就是同步代码块。在同步代码块内部,只能有一个线程同时执行,其他线程需要等待锁被释放后才能进入同步代码块。同步代码块的格式如下:
1.同步代码块
synchronized (lockObj) { // 同步代码块 }
其中,lockObj表示需要保护的对象,可以是任意对象,在多线程环境中必须是共享对象
2.同步方法
使用synchronized修饰方法就是同步方法。同步方法的定义格式如下:
public synchronized void methodName() { // 同步方法体 }
在同步方法内部,会自动获取当前对象的锁,其他线程需要等待锁被释放后才能调用同步方法。
注意,互斥锁只能保护同步代码块或者同步方法内部的代码,而无法保护其他代码。因此,需要保护的代码块或方法需要尽可能缩小范围,避免占用锁的时间过长,影响执行效率。
死锁
死锁是指两个或多个进程在执行过程中,由于竞争资源而陷入无限等待的一种状态。简单来说,死锁是一种资源竞争的结果,进程之间互相等待对方释放资源导致无法继续执行。
例如,当进程A持有资源X,但需要资源Y时,而进程B持有资源Y,但需要资源X时,那么A和B在互相等待对方释放资源之后才能继续执行,导致死锁的产生.
预防死锁的常用方法包括资源分配策略、资源预留、资源抢占等.
持续更新中.....