在 Java 中,多线程是指同时执行两个或多个线程以最大限度地利用 CPU 的过程。 Java 中的线程是一个轻量级进程,只需要较少的资源即可创建和共享进程资源。

多线程和多进程用于 Java 中的多任务处理,但我们更喜欢多线程而不是多进程。 这是因为线程使用共享内存区域有助于节省内存,而且线程之间的内容切换比进程快一点。

线程的生命周期

线程在其生命周期中必须经历五种状态。 此生命周期由 JVM(Java 虚拟机)控制。 这些状态是:

  1. New
  2. Runnable
  3. Running
  4. Non-Runnable (Blocked)
  5. Terminated

New

在这种状态下,一个新线程开始它的生命周期。 这也称为新生线程。 如果在调用 start() 方法之前创建 Thread 类的实例,则线程处于新创建状态。

Runnable

一个线程在一个新生成的线程启动后变为可运行的。 在这种状态下,线程将执行其任务。

Running

当线程调度程序选择线程时,该线程将处于运行状态。

Non-Runnable (Blocked)

该线程在此状态下仍处于活动状态,但目前还没有资格运行。

Terminated

线程因以下原因而终止:

  • 它的 run() 方法要么正常存在,即线程的代码已经执行了程序。
  • 或者由于一些不寻常的错误,如分段错误或未处理的异常。

处于终止状态的线程不会消耗 CPU 的任何周期。

Java线程类

Java Thread 类提供了在线程上创建和执行操作的方法和构造函数。 Java 线程类扩展了 Object 类并实现了 Runnable 接口。

Java Thread方法

这些是 Thread 类中可用的方法:

1. public void start()

它开始执行线程,然后在这个 Thread 对象上调用 run()。

示例:

{    
    public void run()  
    {    
        System.out.println("Thread is running...");    
    }    
    public static void main(String[] args) {    
        StartExp1 thread1=new StartExp1();
        thread1.start();    
    }    
}

输出

Thread is running…

2. public void run()

该线程用于为线程执行操作。 如果线程是使用单独的 Runnable 对象构造的,则实例化 run() 方法。

示例

public class RunExp1 implements Runnable  
{    
    public void run()  
    {    
        System.out.println("Thread is running...");    
    }    
    public static void main(String args[])  
    {    
        RunExp1 r1=new RunExp1();    
        Thread thread1 =new Thread(r1);    
        thread1.start();    
    }    
}  

输出

Thread is running…

2. public void sleep()

这会在指定的时间内阻塞当前正在运行的线程。

示例

public class SleepExp1 extends Thread  
{    
    public void run()  
    {    
        for(int i=1;i<5;i++)  
        {    
            try 
            {  
                Thread.sleep(500);  
            }catch(InterruptedException e){System.out.println(e);}    
            System.out.println(i);    
        }    
    }    
    public static void main(String args[])  
    {    
        SleepExp1 thread1=new SleepExp1();    
        SleepExp1 thread2=new SleepExp1();    
        thread1.start();    
        thread2.start();    
    }    
}  

输出

1

1

2

2

3

3

4

4

4. public static Thread currentThread()

它返回对当前正在运行的线程的引用。

示例

public class CurrentThreadExp extends Thread  
{    
    public void run()  
    {    
        System.out.println(Thread.currentThread().getName());    
    }    
    public static void main(String args[])  
    {    
        CurrentThreadExp thread1=new CurrentThreadExp();    
        CurrentThreadExp thread2=new CurrentThreadExp();    
        thread1.start();    
        thread2.start();    
    }    
} 

输出

Thread-0

Thread-1

5. public void join()

它会导致当前线程阻塞,直到第二个线程终止或经过指定的毫秒数。

示例

public class JoinExample1 extends Thread  
{    
    public void run()  
    {    
        for(int i=1; i<=4; i++)  
        {    
            try 
            {    
                Thread.sleep(500);    
            }catch(Exception e){System.out.println(e);}    
            System.out.println(i);    
        }    
    }    
    public static void main(String args[])  
    {   
        JoinExample1 thread1 = new JoinExample1();    
        JoinExample1 thread2 = new JoinExample1();    
        JoinExample1 thread3 = new JoinExample1();    
        thread1.start();   
       try 
        {    
        thread1.join();    
        }catch(Exception e){System.out.println(e);}    
        thread2.start();   
        thread3.start();    
    }    
}  

输出

1

2

3

4

1

1

2

2

3

3

4

4

6. public final int getPriority()

它用于检查线程的优先级。 创建线程时,会为其分配一些优先级。 此优先级由 JVM 或程序员在创建线程时显式分配。

示例

public class JavaGetPriorityExp extends Thread  
{    
    public void run()  
    {    
        System.out.println("running thread name is:"+Thread.currentThread().getName());    
    }    
    public static void main(String args[])  
    {    
        JavaGetPriorityExp t1 = new JavaGetPriorityExp();    
        JavaGetPriorityExp t2 = new JavaGetPriorityExp();    
        System.out.println("t1 thread priority : " + t1.getPriority());   
        System.out.println("t2 thread priority : " + t2.getPriority());  
        t1.start();    
        t2.start();  
    }    
}  

输出

t1 thread priority : 5

t2 thread priority : 5

running thread name is:Thread-0

running thread name is:Thread-1

7. public final void setPriority()

此方法用于更改线程的优先级。 每个线程的优先级由 1 到 10 的整数表示。线程的默认优先级为 5。

示例

public class JavaSetPriorityExp1 extends Thread  
{    
    public void run()  
    {    
        System.out.println("Priority of thread is: "+Thread.currentThread().getPriority());    
    }    
    public static void main(String args[])  
    {    
        JavaSetPriorityExp1 t1=new JavaSetPriorityExp1();
        t1.setPriority(Thread.MAX_PRIORITY);    
        t1.start();    
    }    
} 

输出

Priority of thread is: 10

8. public final String getName()

线程类的这个方法用于返回线程的名称。 我们不能在我们的程序中覆盖这个方法,因为这个方法是final的。

示例

public class GetNameExample extends Thread  
{    
    public void run()  
    {    
        System.out.println("Thread is running...");    
    }    
    public static void main(String args[])  
    {   
        // creating two threads   
        GetNameExample thread1=new GetNameExample();    
        GetNameExample thread2=new GetNameExample();    
        System.out.println("Name of thread1: "+ thread1.getName());    
        System.out.println("Name of thread2: "+thread2.getName());    
        thread1.start();    
        thread2.start();    
    }    
}

输出

Name of thread1: Thread-0

Name of thread2: Thread-1

Thread is running…

Thread is running…

9. public final void setName()

此方法更改线程的名称。

示例

public class SetNameExample extends Thread  
{    
    public void run()  
    {    
        System.out.println("running...");    
    }    
    public static void main(String args[])  
    {   
        SetNameExample thread1=new SetNameExample();    
        SetNameExample thread2=new SetNameExample();    
        thread1.start();    
        thread2.start();       
        thread1.setName("Kadamb Sachdeva");    
        thread2.setName("Great learning");  
        System.out.println("After changing name of thread1: "+thread1.getName());  
        System.out.println("After changing name of thread2: "+thread2.getName());  
    }    
}

输出

After changing name of thread1: Kadamb Sachdeva

After changing name of thread2: Great Learning

running…

running…

10. public long getId()

它返回线程的标识符。 线程 ID 是创建线程时生成的数字。 此 ID 在其生命周期内无法更改。 但是当线程终止时,ID可以被重用。

示例

public class GetIdExample extends Thread  
{    
    public void run()  
    {    
        System.out.println("running...");    
    }    
    public static void main(String args[])  
    {    
        GetIdExample thread1=new GetIdExample();    
        System.out.println("Name of thread1: "+thread1.getName());  
        System.out.println("Id of thread1: "+thread1.getId());   
        thread1.start();  
    }    
}

输出

Name of thread1: Thread-0

Id of thread1: 21

running…

11. public final boolean isAlive()

此方法检查线程是否处于活动状态。 如果线程类的 start() 方法已被调用且线程尚未死亡,则线程处于活动状态。

示例

public class JavaIsAliveExp extends Thread   
{  
    public void run()  
    {  
        try  
        {  
            Thread.sleep(300);  
            System.out.println("is run() method isAlive "+Thread.currentThread().isAlive());  
        }  
        catch (InterruptedException ie) {  
        }  
    }  
    public static void main(String[] args)  
    {  
        JavaIsAliveExp thread1 = new JavaIsAliveExp();  
        System.out.println("before starting thread isAlive: "+thread1.isAlive());  
        thread1.start();  
        System.out.println("after starting thread isAlive: "+thread1.isAlive());  
    }  
} 

输出

before starting thread isAlive: false

after starting thread isAlive: true

is run() method isAlive true

12. public static void yield()

该方法暂停当前线程的执行以暂时执行其他线程。

示例

public class JavaYieldExp extends Thread  
{  
    public void run()  
    {  
        for (int i=0; i<3 ; i++)  
            System.out.println(Thread.currentThread().getName() + " in control");  
    }  
    public static void main(String[]args)  
    {  
        JavaYieldExp thread1 = new JavaYieldExp();  
        JavaYieldExp thread2 = new JavaYieldExp();  
        thread1.start();  
        thread2.start();  
        for (int i=0; i<3; i++)  
        {  
            thread1.yield();  
            System.out.println(Thread.currentThread().getName() + " in control");  
        }  
    }  
}

输出

main in control

main in control

main in control

Thread-0 in control

Thread-0 in control

Thread-0 in control

Thread-1 in control

Thread-1 in control

Thread-1 in control

13. public final void suspend()

该方法用于暂时挂起当前正在运行的线程。 使用 resume() 方法,您可以恢复挂起的线程。

示例

public class JavaSuspendExp extends Thread  
{    
    public void run()  
    {    
        for(int i=1; i<5; i++)  
        {    
            try 
            {  
                 sleep(500);  
                 System.out.println(Thread.currentThread().getName());    
            }catch(InterruptedException e){System.out.println(e);}    
            System.out.println(i);    
        }    
    }    
    public static void main(String args[])  
    {    
        JavaSuspendExp thread1=new JavaSuspendExp ();    
        JavaSuspendExp thread2=new JavaSuspendExp ();   
        JavaSuspendExp thread3=new JavaSuspendExp ();
        thread1.start();  
        thread2.start();  
        thread2.suspend();   
        thread3.start();  
    }    
}

输出

Thread-0

1

Thread-2

1

Thread-0

2

Thread-2

2

Thread-0

3

Thread-2

3

Thread-0

4

Thread-2

4

14. public final void resume()

此方法用于恢复挂起的线程。 它仅与 suspend() 方法一起使用。

public class JavaResumeExp extends Thread  
{    
    public void run()  
    {    
        for(int i=1; i<5; i++)  
        {    
            try 
            {  
                 sleep(500);  
                 System.out.println(Thread.currentThread().getName());    
            }catch(InterruptedException e){System.out.println(e);}    
            System.out.println(i);    
        }    
    }    
    public static void main(String args[])  
    {    
        JavaResumeExp thread1=new JavaResumeExp ();    
        JavaResumeExp thread2=new JavaResumeExp ();   
        JavaResumeExp thread3=new JavaResumeExp ();   
        thread1.start();  
        thread2.start();  
        thread2.suspend();
        thread3.start();   
        thread2.resume();
    }    
}

输出

Thread-0

1

Thread-2

1

Thread-1

1

Thread-0

2

Thread-2

2

Thread-1

2

Thread-0

3

Thread-2

3

Thread-1

3

Thread-0

4

Thread-2

4

Thread-1

4

15. public final void stop()

顾名思义,此方法用于停止当前正在运行的线程。 请记住,一旦线程执行停止,就无法重新启动。

示例

public class JavaStopExp extends Thread  
{    
    public void run()  
    {    
        for(int i=1; i<5; i++)  
        {    
            try 
            {  
                sleep(500);  
                System.out.println(Thread.currentThread().getName());    
            }catch(InterruptedException e){System.out.println(e);}    
            System.out.println(i);    
        }    
    }    
    public static void main(String args[])  
    {    
        JavaStopExp thread1=new JavaStopExp ();    
        JavaStopExp thread2=new JavaStopExp ();   
        JavaStopExp thread3=new JavaStopExp ();   
        thread1.start();  
        thread2.start();  
        thread3.stop();  
        System.out.println("Thread thread3 is stopped");    
    }    
}

16. public void destroy()

此线程方法会破坏线程组及其子组。

示例

public class JavaDestroyExp extends Thread   
{  
    JavaDestroyExp(String threadname, ThreadGroup tg)  
    {  
        super(tg, threadname);  
        start();  
    }  
    public void run()  
    {  
        for (int i = 0; i < 2; i++)   
        {  
            try 
            {  
                Thread.sleep(10);  
            }  
            catch (InterruptedException ex) {  
                System.out.println("Exception encounterted");}  
        }  
        System.out.println(Thread.currentThread().getName() +  
              " finished executing");  
    }  
    public static void main(String arg[]) throws InterruptedException, SecurityException  
    {  
        ThreadGroup g1 = new ThreadGroup("Parent thread"); 
        ThreadGroup g2 = new ThreadGroup(g1, "child thread");  
        JavaDestroyExp thread1 = new JavaDestroyExp("Thread-1", g1);  
        JavaDestroyExp thread2 = new JavaDestroyExp("Thread-2", g1);  
        thread1.join();  
        thread2.join();  
        g2.destroy();  
        System.out.println(g2.getName() + " destroyed");  
        g1.destroy();  
        System.out.println(g1.getName() + " destroyed");  
    }  
} 

输出

Thread-1 finished executing

Thread-2 finished executing

child thread destroyed

Parent thread destroyed

17. public final boolean isDaemon()

此线程方法将检查线程是否为守护线程。 如果是守护线程,则返回true,否则返回false。

对于不了解守护线程的人来说,守护线程是在程序结束时不会阻止 Java 虚拟机 (JVM) 退出但线程仍在运行的线程。

示例

public class JavaIsDaemonExp extends Thread  
{    
    public void run()  
    {    
        //checking for daemon thread    
        if(Thread.currentThread().isDaemon())  
        {  
            System.out.println("daemon thread work");    
        }    
        else 
        {    
            System.out.println("user thread work");    
        }    
    }    
    public static void main(String[] args)  
    {    
        JavaIsDaemonExp thread1=new JavaIsDaemonExp();   
        JavaIsDaemonExp thread2=new JavaIsDaemonExp();    
        JavaIsDaemonExp thread3=new JavaIsDaemonExp();    
        thread1.setDaemon(true);  
        thread1.start();   
        thread2.start();    
        thread3.start();    
    }    
}

输出

daemon thread work

user thread work

user thread work

18. public final void setDaemon(boolean on)

线程的这种方法用于标识或标记线程是守护进程还是用户线程。 当所有用户线程都死掉时,JVM 会自动终止该线程。

该线程方法必须在线程开始执行之前运行。

示例

public class JavaSetDaemonExp1 extends Thread  
{    
    public void run()  
    {    
        if(Thread.currentThread().isDaemon())  
        {  
            System.out.println("daemon thread work");    
        }    
        else 
        {    
            System.out.println("user thread work");    
        }    
    }    
    public static void main(String[] args)  
    {    
        JavaSetDaemonExp1 thread1=new JavaSetDaemonExp1();   
        JavaSetDaemonExp1 thread2=new JavaSetDaemonExp1();    
        JavaSetDaemonExp1 thread3=new JavaSetDaemonExp1();    
        thread1.setDaemon(true);  
        thread1.start();   
        thread2.setDaemon(true);  
        thread2.start();    
        thread3.start();    
    }    
} 

输出

daemon thread work

daemon thread work

user thread work

19. public void interrupt()

线程的这种方法用于中断当前正在执行的线程。 该方法只能在线程处于睡眠或等待状态时调用。

但是如果线程不处于睡眠或等待状态,那么interrupt()方法不会中断线程,而是将中断标志设置为true。

示例

public class JavaInterruptExp1 extends Thread  
{    
    public void run()  
    {    
        try 
        {    
            Thread.sleep(1000);    
            System.out.println("javatpoint");    
        }catch(InterruptedException e){    
            throw new RuntimeException("Thread interrupted..."+e);  
               
        }    
    }    
    public static void main(String args[])  
    {    
        JavaInterruptExp1 thread1=new JavaInterruptExp1();    
        thread1.start();    
        try 
        {    
            thread1.interrupt();    
        }catch(Exception e){System.out.println("Exception handled "+e);}    
    }    
}  

输出

Exception in thread “Thread-0” java.lang.RuntimeException: Thread interrupted…java.lang.InterruptedException: sleep interrupted at JavaInterruptExp1.run(JavaInterruptExp1.java:10)

20. public boolean isInterrupted()

该线程方法用于测试线程是否被中断。 它将内部标志的值作为真或假返回,即如果线程被中断,它将返回真,否则返回假。

示例

public class JavaIsInterruptedExp extends Thread   
{   
    public void run()   
    {   
        for(int i=1;i<=3;i++)   
        {   
            System.out.println("doing task....: "+i);   
        }   
    }   
    public static void main(String args[])throws InterruptedException   
    {   
        JavaIsInterruptedExp thread1=new JavaIsInterruptedExp();   
        JavaIsInterruptedExp thread2=new JavaIsInterruptedExp();   
        thread1.start();   
        thread2.start();  
        System.out.println("is thread interrupted..: "+thread1.isInterrupted());  
        System.out.println("is thread interrupted..: "+thread2.isInterrupted());  
        thread1.interrupt();   
        System.out.println("is thread interrupted..: " +thread1.isInterrupted());   
        System.out.println("is thread interrupted..: "+thread2.isInterrupted());   
    }  
} 

输出

is thread interrupted…: false

is thread interrupted…: false

is thread interrupted…: true

is thread interrupted…: false

doing task….: 1

doing task….: 2

doing task….: 3

doing task….: 1

doing task….: 2

doing task….: 3

21. public static boolean interrupted()

该线程方法用于检查当前线程是否被中断。 如果要连续调用此线程方法两次,则第二次调用将返回 false。

如果线程的中断状态为真,那么这个线程方法会将其设置为假。

示例

public class JavaInterruptedExp extends Thread   
{   
    public void run()   
    {   
        for(int i=1;i<=3;i++)   
        {   
            System.out.println("doing task....: "+i);   
        }   
    }   
    public static void main(String args[])throws InterruptedException   
    {   
        JavaInterruptedExp thread1=new JavaInterruptedExp();   
        JavaInterruptedExp thread2=new JavaInterruptedExp();   
        thread1.start();   
        thread2.start();  
        System.out.println("is thread thread1 interrupted..:"+thread1.interrupted()); 
        thread1.interrupt();   
        System.out.println("is thread thread1 interrupted..:"+thread1.interrupted());   
        System.out.println("is thread thread2 interrupted..:"+thread2.interrupted());   
    }  
} 

输出

is thread thread1 interrupted…: false

is thread thread1 interrupted…: false

is thread thread2 interrupted…: false

doing task….: 1

doing task….: 2

doing task….: 3

doing task….: 1

doing task….: 2

doing task….: 3

22. public static int activeCount()

线程的这个方法用于返回当前执行线程的线程组中的活动线程数。

此线程方法返回的数字只是一个估计数字,因为此方法遍历内部数据结构时线程数会动态变化。

示例

public class JavaActiveCountExp extends Thread   
{  
    JavaActiveCountExp(String threadname, ThreadGroup tg)  
    {  
        super(tg, threadname);  
        start();  
    }  
    public void run()  
    {  
       System.out.println("running thread name is:"
+Thread.currentThread().getName());    
    }  
    public static void main(String arg[])  
    {  
        ThreadGroup g1 = new ThreadGroup("parent thread group");  
          JavaActiveCountExp thread1 = new JavaActiveCountExp("Thread-1", g1);  
        JavaActiveCountExp thread2 = new JavaActiveCountExp("Thread-2", g1);  
          System.out.println("number of active thread: "+ g1.activeCount());  
    }  
}

输出

number of active thread: 2

running thread name is: Thread-1

running thread name is: Thread-2

23. public final void checkAccess()

该线程方法标识当前线程是否具有修改线程的权限。

示例

public class JavaCheckAccessExp extends Thread     
{    
    public void run()  
    {  
        System.out.println(Thread.currentThread().getName()+" finished executing");  
    }  
    public static void main(String arg[]) throws InterruptedException, SecurityException    
    {   
        JavaCheckAccessExp thread1 = new JavaCheckAccessExp();    
        JavaCheckAccessExp thread2 = new JavaCheckAccessExp();    
        thread1.start();  
        thread2.start();  
        thread1.checkAccess();    
        System.out.println(t1.getName() + " has access");    
        thread2.checkAccess();    
        System.out.println(t2.getName() + " has access");    
    }    
}  

输出

Thread-0 has access

Thread-1 has access

Thread-0 finished executing

Thread-1 finished executing

24. public static boolean holdsLock(Object obj)

此线程方法检查当前执行的线程是否持有指定对象的监视器锁。 如果是这样,那么这个线程方法将返回 true。

示例

public class JavaHoldLockExp implements Runnable   
{  
    public void run()   
    {  
        System.out.println("Currently executing thread is: " + Thread.currentThread().getName());  
        System.out.println("Does thread holds lock? " + Thread.holdsLock(this));  
        synchronized (this)   
        {  
            System.out.println("Does thread holds lock? " + Thread.holdsLock(this));  
        }  
    }  
    public static void main(String[] args)   
    {  
        JavaHoldLockExp g1 = new JavaHoldLockExp();  
        Thread thread1 = new Thread(g1);  
        thread1.start();  
    }  
}

输出

Currently executing thread is: Thread-0

Does thread holds lock? false

Does thread holds lock? true

除此之外,还有多种线程方法用于不同的任务和目的。 这些线程方法如下:

  • public static void dumpStack()
  • public StackTraceElement[] getStackTrace()
  • public static int enumerate(Thread[] tarray)
  • public Thread.State getState()
  • public final ThreadGroup getThreadGroup()
  • public String toString()
  • public final void notify()
  • public final void notifyAll()
  • public void setContextClassLoader(ClassLoader cl)
  • public ClassLoader getContextClassLoader()
  • public static Thread.UncaughtExceptionHandler getDefaultUncaughtExceptionHandler()
  • public static void setDefaultUncaughtExceptionHandler(Thread.UncaughtExceptionHandler eh)

创建线程

在 Java 中使用多线程时,您可以使用两种方式创建线程:

  1. 通过扩展 Thread 类
  2. 通过实现 Runnable 接口

什么是Thread类

Thread 类提供了在线程上创建和执行操作的方法和构造函数。 Thread 类扩展了 Object 类并实现了 Runnable 接口。

Thread类中使用了各种构造函数,但常用的构造函数有:

  • Thread()
  • Thread(String name)
  • Thread(Runnable r)
  • Thread(Runnable r,String name)

此外,如前所述,有多种线程方法用于不同的目的和任务。

因此,这些构造函数和方法是由 Thread 类提供的,用于在线程上执行各种操作。

Runnable接口是什么

Runnable 接口被实现,其实例旨在由线程执行。 它只有一种方法 run()。

public void run() 这用于为线程执行操作。

启动一个线程

在 Java 中进行多线程时,要启动一个新创建的线程,使用 start() 方法。

  • 一个新线程开始(使用新的调用堆栈)。
  • 线程从 New 状态移动到 Runnable 状态。
  • 当线程有机会执行时,它的目标 run() 方法将运行。

通过扩展 Thread 类的 Java Thread 示例

class Multi extends Thread{  
public void run(){  
System.out.println("thread is running...");  
}  
public static void main(String args[]){  
Multi thread1=new Multi();  
thread1.start();  
 }  
} 

输出

thread is running…

通过实现 Runnable 接口的 Java 线程示例

class Multi3 implements Runnable{  
public void run(){  
System.out.println("thread is running...");  
}  
 
public static void main(String args[]){  
Multi3 m1=new Multi3();  
Thread thread1 =new Thread(m1);  
thread1.start();  
 }  
} 

输出

thread is running…

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐