JAVA多线程机制之线程创建

简介:

在Java中创建线程有两种方式,一种是继承Thread,另一种是实现Runnable接口,Thread实际上也实现了Runnable接口。

Thread

构造方法

方法名 说明
Thread() 分配新的 Thread 对象
Thread(Runnable target) 分配新的 Thread 对象
Thread(Runnable target, String name) 分配新的 Thread 对象
Thread(String name) 分配新的 Thread 对象
Thread(ThreadGroup group, Runnable target) 分配新的 Thread 对象
Thread(ThreadGroup group, Runnable target, String name) 分配新的 Thread 对象,以便将 target 作为其运行对象,将指定的 name 作为其名称,并作为 group 所引用的线程组的一员
Thread(ThreadGroup group, Runnable target, String name, long stackSize) 分配新的 Thread 对象,以便将 target 作为其运行对象,将指定的 name 作为其名称,作为 group 所引用的线程组的一员,并具有指定的堆栈大小
Thread(ThreadGroup group, String name) 分配新的 Thread 对象

方法摘要

返回值 方法名 说明
static int activeCount() 返回当前线程的线程组中活动线程的数目
void checkAccess() 判定当前运行的线程是否有权修改该线程
static Thread currentThread() 返回对当前正在执行的线程对象的引用
static void dumpStack() 将当前线程的堆栈跟踪打印至标准错误流
static int enumerate(Thread[] tarray) 将当前线程的线程组及其子组中的每一个活动线程复制到指定的数组中
static Map<Thread,StackTraceElement[]> getAllStackTraces() 返回所有活动线程的堆栈跟踪的一个映射
ClassLoader getContextClassLoader() 返回该线程的上下文 ClassLoader
static Thread.UncaughtExceptionHandler getDefaultUncaughtExceptionHandler() 返回线程由于未捕获到异常而突然终止时调用的默认处理程序
long getId() 返回该线程的标识符
String getName() 返回该线程的名称
int getPriority() 返回线程的优先级
StackTraceElement[] getStackTrace() 返回一个表示该线程堆栈转储的堆栈跟踪元素数组
Thread.State getState() 返回该线程的状态
ThreadGroup getThreadGroup() 返回该线程所属的线程组
Thread.UncaughtExceptionHandler getUncaughtExceptionHandler() 返回该线程由于未捕获到异常而突然终止时调用的处理程序
static boolean holdsLock(Object obj) 当且仅当当前线程在指定的对象上保持监视器锁时,才返回 true
void interrupt() 中断线程
static boolean interrupted() 测试当前线程是否已经中断
boolean isAlive() 测试线程是否处于活动状态
boolean isDaemon() 测试该线程是否为守护线程
boolean isInterrupted() 测试线程是否已经中断
void join() 等待该线程终止
void join(long millis) 等待该线程终止的时间最长为 millis 毫秒
void join(long millis, int nanos) 等待该线程终止的时间最长为 millis 毫秒 + nanos 纳秒
void run() 如果该线程是使用独立的 Runnable 运行对象构造的,则调用该 Runnable 对象的 run 方法;否则,该方法不执行任何操作并返回
void setContextClassLoader(ClassLoader cl) 设置该线程的上下文 ClassLoader
void setDaemon(boolean on) 将该线程标记为守护线程或用户线程
static void setDefaultUncaughtExceptionHandler(Thread.UncaughtExceptionHandler eh) 设置当线程由于未捕获到异常而突然终止,并且没有为该线程定义其他处理程序时所调用的默认处理程序
void setName(String name) 改变线程名称,使之与参数 name 相同
void setPriority(int newPriority) 更改线程的优先级
void setUncaughtExceptionHandler(Thread.UncaughtExceptionHandler eh) 设置该线程由于未捕获到异常而突然终止时调用的处理程序
static void sleep(long millis) 在指定的毫秒数内让当前正在执行的线程休眠(暂停执行),此操作受到系统计时器和调度程序精度和准确性的影响
static void sleep(long millis, int nanos) 在指定的毫秒数加指定的纳秒数内让当前正在执行的线程休眠(暂停执行),此操作受到系统计时器和调度程序精度和准确性的影响
void start() 使该线程开始执行;Java 虚拟机调用该线程的 run 方法
String toString() 返回该线程的字符串表示形式,包括线程名称、优先级和线程组
static void yield() 暂停当前正在执行的线程对象,并执行其他线程

使用示例

public class ThreadDemo
{
   public static void main(String[] args)
   {
      PrintThread thread1 = new PrintThread();
      PrintThread thread2 = new PrintThread();
      // 通过start方法启动线程
      thread1.start();
      thread2.start();
   }
}

/**
 * 继承Thread
 * 
 * @author jianggujin
 * 
 */
class PrintThread extends Thread
{
   /**
    * 重写run方法,线程执行的逻辑写在该方法内
    */
   @Override
   public void run()
   {
      for (int i = 0; i < 10; i++)
      {
         try
         {
            // 使线程休眠100毫秒,使结果更直观
            Thread.sleep(100);
         }
         catch (InterruptedException e)
         {
            e.printStackTrace();
         }
         System.out.println(getName() + ":" + i);
      }
   }
}

运行结果如下:
Thread-1:0
Thread-0:0
Thread-0:1
Thread-1:1
Thread-0:2
Thread-1:2
Thread-0:3
Thread-1:3
Thread-0:4
Thread-1:4
Thread-1:5
Thread-0:5
Thread-1:6
Thread-0:6
Thread-0:7
Thread-1:7
Thread-0:8
Thread-1:8
Thread-1:9
Thread-0:9

在上面的示例中,我们使用了继承Thread的方式创建了线程对象并通过start()方法启动了线程,在例子中,我们启动了两个线程,线程只是简单的输出一句话,通过查看运行结果,我们可以发现两个线程是交错执行的。

Runnable

方法摘要

返回值 方法名 说明
void run() 使用实现接口 Runnable 的对象创建一个线程时,启动该线程将导致在独立执行的线程中调用对象的 run 方法

使用示例

public class ThreadDemo
{
   public static void main(String[] args)
   {
      PrintThread thread1 = new PrintThread("Thread-0");
      PrintThread thread2 = new PrintThread("Thread-1");
      // 使用该种方式启动线程
      new Thread(thread1).start();
      new Thread(thread2).start();
   }
}

/**
 * 实现Runnable接口
 * 
 * @author jianggujin
 * 
 */
class PrintThread implements Runnable
{
   // 用于标识线程
   private String name;

   public PrintThread(String name)
   {
      this.name = name;
   }

   /**
    * 实现run方法,线程执行的逻辑写在该方法内
    */
   @Override
   public void run()
   {
      for (int i = 0; i < 10; i++)
      {
         try
         {
            // 使线程休眠100毫秒,使结果更直观
            Thread.sleep(100);
         }
         catch (InterruptedException e)
         {
            e.printStackTrace();
         }
         System.out.println(getName() + ":" + i);
      }
   }

   public String getName()
   {
      return name;
   }
}

运行结果:
Thread-0:0
Thread-1:0
Thread-1:1
Thread-0:1
Thread-0:2
Thread-1:2
Thread-0:3
Thread-1:3
Thread-0:4
Thread-1:4
Thread-1:5
Thread-0:5
Thread-0:6
Thread-1:6
Thread-0:7
Thread-1:7
Thread-0:8
Thread-1:8
Thread-1:9
Thread-0:9

join()

有的时候,我们希望当一个线程执行完后,在继续执行其他线程,比如一些初始化工作。这个时候我们可以使用join()方法,join()方法可以等待该线程终止。

使用示例

public class ThreadDemo
{
   public static void main(String[] args)
   {
      PrintThread thread1 = new PrintThread();
      PrintThread thread2 = new PrintThread();
      // 通过start方法启动线程
      thread1.start();
      try
      {
         //等待线程执行结束
         thread1.join();
      }
      catch (InterruptedException e)
      {
         e.printStackTrace();
      }
      thread2.start();
   }
}

/**
 * 继承Thread
 * 
 * @author jianggujin
 * 
 */
class PrintThread extends Thread
{
   /**
    * 重写run方法,线程执行的逻辑写在该方法内
    */
   @Override
   public void run()
   {
      for (int i = 0; i < 10; i++)
      {
         try
         {
            // 使线程休眠100毫秒,使结果更直观
            Thread.sleep(100);
         }
         catch (InterruptedException e)
         {
            e.printStackTrace();
         }
         System.out.println(getName() + ":" + i);
      }
   }
}

运行结果:
Thread-0:0
Thread-0:1
Thread-0:2
Thread-0:3
Thread-0:4
Thread-0:5
Thread-0:6
Thread-0:7
Thread-0:8
Thread-0:9
Thread-1:0
Thread-1:1
Thread-1:2
Thread-1:3
Thread-1:4
Thread-1:5
Thread-1:6
Thread-1:7
Thread-1:8
Thread-1:9

通过运行结果我们可以看到,当我们使用join方法后,会等待线程执行结束再继续执行另一个线程。

目录
相关文章
|
18小时前
|
Java 数据库连接
深入理解Java异常处理机制
【4月更文挑战第24天】本文将探讨Java中的异常处理机制,包括异常的概念、分类、捕获和抛出等方面。通过深入了解异常处理机制,可以帮助我们编写更加健壮的程序,提高代码的可读性和可维护性。
|
21小时前
|
缓存 Java
【Java基础】简说多线程(上)
【Java基础】简说多线程(上)
5 0
|
1天前
|
并行计算 算法 安全
Java从入门到精通:2.1.3深入学习Java核心技术——掌握Java多线程编程
Java从入门到精通:2.1.3深入学习Java核心技术——掌握Java多线程编程
|
1天前
|
安全 Java 编译器
是时候来唠一唠synchronized关键字了,Java多线程的必问考点!
本文简要介绍了Java中的`synchronized`关键字,它是用于保证多线程环境下的同步,解决原子性、可见性和顺序性问题。从JDK1.6开始,synchronized进行了优化,性能得到提升,现在仍可在项目中使用。synchronized有三种用法:修饰实例方法、静态方法和代码块。文章还讨论了synchronized修饰代码块的锁对象、静态与非静态方法调用的互斥性,以及构造方法不能被同步修饰。此外,通过反汇编展示了`synchronized`在方法和代码块上的底层实现,涉及ObjectMonitor和monitorenter/monitorexit指令。
6 0
|
1天前
|
监控 安全 Java
在Java中如何优雅的停止一个线程?可别再用Thread.stop()了!
在Java中如何优雅的停止一个线程?可别再用Thread.stop()了!
7 2
|
1天前
|
Java 调度
Java面试必考题之线程的生命周期,结合源码,透彻讲解!
Java面试必考题之线程的生命周期,结合源码,透彻讲解!
8 1
|
1天前
|
安全 Java
Java基础教程(15)-多线程基础
【4月更文挑战第15天】Java内置多线程支持,通过Thread类或Runnable接口实现。线程状态包括New、Runnable、Blocked、Waiting、Timed Waiting和Terminated。启动线程调用start(),中断线程用interrupt(),同步用synchronized关键字。线程安全包如java.util.concurrent提供并发集合和原子操作。线程池如ExecutorService简化任务管理,Callable接口允许返回值,Future配合获取异步结果。Java 8引入CompletableFuture支持回调。
|
2天前
|
安全 Java 调度
Java线程:深入理解与实战应用
Java线程:深入理解与实战应用
15 0
|
2天前
|
Java
Java中的并发编程:理解和应用线程池
【4月更文挑战第23天】在现代的Java应用程序中,性能和资源的有效利用已经成为了一个重要的考量因素。并发编程是提高应用程序性能的关键手段之一,而线程池则是实现高效并发的重要工具。本文将深入探讨Java中的线程池,包括其基本原理、优势、以及如何在实际开发中有效地使用线程池。我们将通过实例和代码片段,帮助读者理解线程池的概念,并学习如何在Java应用中合理地使用线程池。
|
6天前
|
安全 Java
深入理解 Java 多线程和并发工具类
【4月更文挑战第19天】本文探讨了Java多线程和并发工具类在实现高性能应用程序中的关键作用。通过继承`Thread`或实现`Runnable`创建线程,利用`Executors`管理线程池,以及使用`Semaphore`、`CountDownLatch`和`CyclicBarrier`进行线程同步。保证线程安全、实现线程协作和性能调优(如设置线程池大小、避免不必要同步)是重要环节。理解并恰当运用这些工具能提升程序效率和可靠性。