一、什么是Java Thread
Java Thread是指Java里的线程。线程是程序执行的一条路线,使得程序可以同时运行多个任务。与进程不同,线程在同一时间内只能有一个被执行,但是CPU可以在多条线程之间快速切换。Java线程是轻量级的,因为它们都是由线程控制器来管理的。
二、Java Thread的创建
Java Thread的创建有两种方式。第一种是继承Thread类,第二种是实现Runnable接口。
1、继承Thread类
public class MyThread extends Thread{ public void run(){ //指定任务内容 } }
创建线程实际上就是创建一个MyThread对象,而这个对象中的run()方法就是要执行的任务内容。调用start()方法后,线程就会被启动并执行run()方法。
2、实现Runnable接口
public class MyRunnable implements Runnable{ public void run(){ //指定任务内容 } }
创建线程时需要传入一个Runnable对象。Runnable对象中的run()方法就是要执行的任务内容。和继承Thread类不同,在实现Runnable接口时,一个对象可以被多个线程共享,从而达到线程共享数据的效果。
三、Java Thread的同步
在多线程执行的过程中,如果多个线程同时对同一个数据进行修改,就会出现数据不一致的问题。为了解决这个问题,就需要对线程进行同步。
1、synchronized关键字
synchronized关键字用于保护一个临界区,使得只能有一个线程进入临界区进行操作,其他线程则需要等待。synchronized关键字可以用在方法上或者代码块中,用法如下:
1.1、方法上锁
public synchronized void doSomething(){ //需要同步的代码 }
1.2、代码块中锁
public void doSomething(){ synchronized(this){ //需要同步的代码 } }
2、volatile关键字
volatile关键字用于保证线程中变量的可见性。当一个变量声明为volatile时,在一个线程中对该变量的修改会马上被其他线程可见。在Java内存模型中,volatile变量可以被看作是一种比synchronized更轻量级的同步机制。用法如下:
public volatile boolean flag = true;
四、Java Thread的状态
Java Thread一共有6种状态:新建状态、就绪状态、运行状态、阻塞状态、等待状态和死亡状态。
1、新建状态
线程创建后处于新建(New)状态。此时线程还没有被启动,也还没有分配到操作系统资源。这时线程已经进入了Java虚拟机的线程等待队列中。
2、就绪状态
当线程被启动后,进入了就绪(Runnable)状态。此时线程已经被分配到了操作系统资源,但它还没有取得CPU执行权。这时线程已经进入了Java虚拟机的线程就绪队列中。
3、运行状态
当线程获得了CPU执行权后,就处于运行(Running)状态。此时线程正在执行任务的代码。
4、阻塞状态
当线程调用了sleep()、wait()、join()等方法时,它进入了阻塞(Blocked)状态。在这种状态下,线程仍然占有操作系统分配的资源,但它不会执行任何代码,处于静止状态。只有当sleep()时间到、wait()条件满足或join()连接结束,阻塞状态的线程才会重新进入到就绪状态中。
5、等待状态
当线程调用了wait()、join()等方法后,并且没有指定等待时间,线程会进入等待(Waiting)状态,此状态下线程会释放它所占有的所有资源。线程只有在接收到notify()或notifyAll()消息后,才会重新进入到就绪状态中。
6、死亡状态
当线程的run()方法执行结束后,线程进入了死亡(Dead)状态。这个线程不能再重新启动,它的所有资源都会被释放。
五、Java Thread常用方法
Java Thread提供了一些非常常用的方法,我们可以根据需求来灵活运用。
1、start()方法
start()方法是真正启动一个线程的方法。当调用了start()方法后,线程就会开始执行,执行的内容是run()方法中的内容。
2、join()方法
join()方法使得调用该方法的线程优先执行,而其他线程等到该线程执行完成后再继续执行。
public class MyThread extends Thread{ public void run(){ System.out.println("线程执行开始"); try{ Thread.sleep(5000); }catch(Exception e){ } System.out.println("线程执行结束"); } } public static void main(String[] args){ MyThread myThread = new MyThread(); myThread.start(); try{ myThread.join(); }catch(Exception e){ } System.out.println("主线程执行结束"); }
以上代码将输出以下内容:
线程执行开始 线程执行结束 主线程执行结束
3、yield()方法
yield()方法是暂停当前正在执行的线程对象,并执行其他线程。
public static void main(String[] args){ new Thread(){ public void run(){ System.out.println("线程1开始执行"); Thread.yield(); System.out.println("线程1结束执行"); } }.start(); new Thread(){ public void run(){ System.out.println("线程2开始执行"); System.out.println("线程2结束执行"); } }.start(); }
以上代码将输出以下内容:
线程1开始执行 线程2开始执行 线程2结束执行 线程1结束执行
4、sleep()方法
sleep()方法使得调用该方法的线程暂停指定的时间,让其他线程有机会执行。
public static void main(String[] args){ new Thread(){ public void run(){ System.out.println("线程1开始执行"); try{ Thread.sleep(5000); }catch(Exception e){ } System.out.println("线程1结束执行"); } }.start(); new Thread(){ public void run(){ System.out.println("线程2开始执行"); System.out.println("线程2结束执行"); } }.start(); }
以上代码将输出以下内容:
线程1开始执行 线程2开始执行 线程2结束执行 线程1结束执行
六、Java Thread的异常处理
线程在执行过程中可能会发生异常,为了保证线程能够正常运行,需要对线程执行代码进行异常处理。Java Thread的异常处理通常使用try-catch-finally语句。
public static void main(String[] args){ Thread thread = new Thread(){ public void run(){ try{ //需要执行的代码 }catch(Exception e){ //异常处理的代码 }finally{ //释放资源的代码 } } }; }
七、Java Thread的线程池
Java ThreadPoolExecutor是Java中线程池的实现。线程池是一种能够提高程序效率和稳定性的资源管理机制。在使用线程池的时候,一般需要指定线程数量和等待队列的长度。
public static void main(String[] args){ ExecutorService executorService = Executors.newFixedThreadPool(10); for(int i=0;i<100;i++){ executorService.execute(new Runnable(){ public void run(){ //执行代码 } }); } executorService.shutdown(); }
八、总结
Java Thread是实现多线程的重要机制,在我们的日常开发中有着非常广泛的应用。本文从Java Thread的创建、同步、状态、常用方法、异常处理和线程池6个方面详细讲述了Java Thread的知识点,可以帮助读者更好地掌握Java Thread的使用方法。