Java中的多线程基本介绍
在 Java 中,多线程是指同时执行两个或多个线程以最大限度地利用 CPU 的过程。 Java 中的线程是一个轻量级进程,只需要较少的资源即可创建和共享进程资源。多线程和多进程用于 Java 中的多任务处理,但我们更喜欢多线程而不是多进程。 这是因为线程使用共享内存区域有助于节省内存,而且线程之间的内容切换比进程快一点。线程的生命周期线程在其生命周期中必须经历五种状态。 此生命周期由 JVM(Ja
在 Java 中,多线程是指同时执行两个或多个线程以最大限度地利用 CPU 的过程。 Java 中的线程是一个轻量级进程,只需要较少的资源即可创建和共享进程资源。
多线程和多进程用于 Java 中的多任务处理,但我们更喜欢多线程而不是多进程。 这是因为线程使用共享内存区域有助于节省内存,而且线程之间的内容切换比进程快一点。
线程的生命周期
线程在其生命周期中必须经历五种状态。 此生命周期由 JVM(Java 虚拟机)控制。 这些状态是:
- New
- Runnable
- Running
- Non-Runnable (Blocked)
- 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 中使用多线程时,您可以使用两种方式创建线程:
- 通过扩展 Thread 类
- 通过实现 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…
更多推荐
所有评论(0)