多线程问题

什么是线程

线程是cpu调度和执行的单位,一个程序的运行伴随着的是一个进程的执行,而一个进程是由一个或多个线程来完成的,通过cpu调度资源在很短时间切换主线程和子线程并行,交替执行来做到看似多个线程同时进行的状态,这种现象也叫做多线程,在多线程中有时候也会存在多个线程同时访问一个资源,所以在这里就又引出了线程的并发问题,如果并发控制没有做好,会导致多线程之间内存交互,最终导致底层数据不一致的问题。

线程的生命周期

我认为周期就是从开始到结束,那线程的周期的开始就是从创建线程,到执行start()线程进入资源排队等待执行,到执行run()方法到运行状态,如果有堵塞那就让出cpu资源就重新排队等待cpu分配资源,没有堵塞继续执行,直到线程结束死亡到这个状态一个线程的生命周期也就结束了

线程的优先级

每个线程都有优先级,线程的优先级用整数数字表示,范围从1到10,一个线程如果没有专门的给他设置优先级的话默认是5。线程的优先级一是用于标记线程的重要性,二是理论上来说设置不同的新城等级在cpu分配资源的时候的概率是不同的,等级越高概率越大,但是既然是概率问题那实际上真的在实际应用中优先级低的线程执行顺序不一定在优先级高的线程之后,有可能是在其之前,所以具体最终线程执行的顺序还是要看实际cpu是怎样分配资源的。

// 设置线程优先级
public final void setPriority(int priority)

Thread 常用的方法

非私有方法

start() //启动线程

setName(String name) //设置线程名称

setPriority(int priority) //设置线程优先级

setDaemon(boolean on) //设置线程是主线程还是

join(long millisec) //守护线程或用户线程。

sleep(long millisec) //设置线程休眠时间

join(long millisec) //等待线程终止的时长

interrupt() //终端线程

私有方法

yield() //暂停当前正在执行的线程对象,并执行其他线程。

sleep(long millisec) //让当前正在执行的线程休眠(暂停执行)

holdsLock(Object x) //当且仅当当前线程在指定的对象上保持监视器锁时,才返回 true。

dumpStack() //将当前线程的堆栈跟踪打印至标准错误流。

currentThread().isInterrupted() // 检查当前线程是不是中断状态

线程的行为

线程的行为包括终止、中断和暂停,是通过特定的API和方法来控制的。

1. 线程的终止

定义:线程的终止是指线程的执行结束或被中断的过程。线程可以在完成其任务后自然终止,也可以通过外部干预(如中断)来提前终止。

实现方式

  • 自然终止:线程执行完其run方法中的所有代码后,将自动终止。
  • 通过interrupt方法:调用线程的interrupt()方法不会立即停止线程,而是将线程的中断状态设置为true。线程应定期检查其中断状态,并在适当的时候自行终止。
  • 使用标志位:通过设置一个共享的标志位(如volatile类型的变量),线程可以在检查到这个标志位被设置为终止状态时退出执行。
  • 抛出异常:当线程中抛出未捕获的异常时,线程会终止执行。

注意事项:线程终止并不是立即发生的,而是需要等待线程执行的代码块或方法结束后才会终止。因此,在编写多线程代码时,需要注意线程的终止条件和线程的安全退出。

2. 线程的中断

定义:线程的中断是一种协作机制,通过发送中断信号来请求线程提前终止其当前工作。

实现方式

  • 调用interrupt()方法:其他线程可以调用目标线程的interrupt()方法来发送中断信号。被中断的线程可以通过检查其中断状态(Thread.currentThread().isInterrupted())或捕获InterruptedException异常来响应中断。
  • 阻塞方法响应:当线程在调用某些阻塞方法(如sleep()wait()join()等)时被中断,这些方法会抛出InterruptedException异常。线程可以捕获这个异常,并决定如何处理(如退出循环、清理资源等)。

注意事项:中断仅仅是一个请求,线程需要自行检查中断状态并决定如何响应。同时,中断状态是可以被清除的(通过调用interrupted()方法),因此需要在适当的时机重新检查中断状态。

3. 线程的暂停(在Java中的模拟方式)

注意:Java没有直接提供暂停线程的API,因为这样做可能会导致死锁或其他并发问题。但是,可以通过以下方式模拟暂停效果:

  • 使用sleep()方法Thread.sleep(long millis)方法可以让当前线程暂停执行指定的毫秒数。然而,这并不会释放锁(如果线程持有锁的话),并且它会使线程进入阻塞状态。
  • 使用wait()方法:通过调用对象的wait()方法,线程可以在该对象的监视器上等待,从而暂停执行。但是,这通常用于线程间的通信,而不是简单地暂停线程。
  • 使用LockCondition:通过Lock对象获取Condition对象,并使用Conditionawait()方法来暂停线程。这种方式比wait()/notify()更加灵活和强大。

注意事项:由于Java没有直接提供暂停线程的API,因此应该谨慎使用上述方法来模拟暂停效果。特别是要注意,暂停线程可能会导致资源无法及时释放或线程无法及时响应外部事件。

守护线程、用户线程

守护线程通常用于执行一些后台任务,如垃圾回收、内存管理、日志记录、系统监控等,这些任务对于应用程序的运行不是必须的,守护线程中产生的新线程默认也是守护线程。

用户线程是指被创建的普通线程,它们是程序的核心部分,适用于执行程序的主要逻辑和任务,如处理用户输入、进行数据处理、与数据库交互等。在多线程程序中,用户线程可以并行或并发地执行多个任务,以提高程序的执行效率和响应速度。

线程的几个主要概念

线程同步

线程间通信

线程死锁

线程控制:挂起、停止和恢复

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值