先说结论
在大多数情况下,推荐使用 Runnable
接口。Runnable相比来说使用起来更灵活方便维护,但是有特殊需求的时候要用到Thread类会好一些,比如当你需要直接控制线程或在特殊情况下进行线程管理时。
Runnable接口的使用
很简单,首先实现接口,然后创建实现接口的对象,再将Runnable对象传给Thread构造方法,接着启动线程就可以了
运行结果
Runnable接口是一个函数式接口,它只包含一个抽象方法 run()
。通过实现该接口,你可以将多线程任务逻辑从线程控制中分离出来。
Thread类的使用
Theard类的使用方法是,先继承Thread类,然后写一个run方法来线程执行的任务逻辑,之后在主函数里调用就可以了
运行结果
这种方法在需要多重继承或与其他接口协同工作的情况下,会比较繁琐,但前边也说了,在某些情况下会更好用
相关知识
众所周知,线程是运行的最小单位,但它也具有生命周期,线程在运行过程中有多个状态,包括新建(New)、就绪(Runnable)、运行(Running)、阻塞(Blocked)、等待(Waiting)、超时等待(Timed Waiting)、终止(Terminated)。
如果你在意管理线程的创建、启动、调度和控制,那Thread会更好
线程的控制: Thread
类提供了一些方法来控制线程的行为,如 sleep()
用于使线程休眠一段时间,join()
用于等待一个线程的结束。(上面代码有写)
线程优先级: 每个线程都有一个优先级,用整数表示,范围为1到10。线程的优先级可以通过 setPriority()
方法设置。
线程组: 可以使用 ThreadGroup
类将线程组织在一起。线程组可以帮助你对一组线程进行集中管理。
守护线程(Daemon Thread): 守护线程是一种在程序运行时在后台提供服务的线程。当所有非守护线程结束时,守护线程会被强制退出。
还有线程同步: 当多个线程共享同一资源时,可能导致数据不一致或其他问题。这会导致竞态条件的产生,造成都用不成的后果。打个比方,很多个很急的人(线程),争抢一个没有门洗手间(资源),会导致很多人挤在洗手间(资源)里,结果一个都解决不了(调用或者更改数据)。要解决这个问题的方法就是给洗手间装上门安上锁,让他们一个一个进出。这在Java里就是synchronized
关键字和ReentrantLock等并发工具。
这个我之前的文章有介绍看怎么用就行。