在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方法后,会等待线程执行结束再继续执行另一个线程。