您的位置:

Java Thread

一、什么是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的使用方法。