ADeveloperH Blog

Meet a better self !

Android 周边技术分享


Java中多线程线程的控制及常用方法

1 线程的控制方法

1.1 休眠线程

使用sleep()方法来使当前线程休眠,不再向下执行。该方法是Thread的静态方法:

public static void sleep(long millis) throws InterruptedException
	millis - 以毫秒为单位的休眠时间。 
public static void sleep(long millis, int nanos) throws InterruptedException
	millis - 以毫秒为单位的休眠时间。
   nanos - 要休眠的另外 0-999999 纳秒。

1.2 加入线程

使用join()方法来使其他线程等待调用了join()方法的对象(线程)先执行。该方法属于Thread对象的方法:

public final void join() throws InterruptedException
	等待该线程终止。直到该线程执行完成后其他线程才执行。
public final void join(long millis, int nanos) throws InterruptedException
	等待该线程终止的时间最长为 millis 毫秒 + nanos 纳秒。 
	millis - 以毫秒为单位的等待时间。
	nanos - 要等待的 0-999999 附加纳秒。 
public final void join(long millis) throws InterruptedException
	    等待该线程终止的时间最长为 millis 毫秒。超时为 0 意味着要一直等下去。
	millis - 以毫秒为单位的等待时间。

1.3 礼让线程

使用yield()方法来使暂停当前正在执行的线程对象,来执行其他线程。该方法是Thread的静态方法:

public static void yield()
	暂停当前正在执行的线程对象,并执行其他线程。 

1.4 守护线程(用户线程)

使用setDaemon()方法使调用该方法的对象被标记为守护线程。守护线程在其他线程终止后也会终止。当正在运行的所有线程都是守护线程时JAVA虚拟机会退出。

public final void setDaemon(boolean on)
将该线程标记为守护线程或用户线程。当正在运行的线程都是守护线程时,Java 虚拟机退出。 

该方法必须在启动线程前调用。 该方法首先调用该线程的 checkAccess 方法,且不带任何参数。这可能抛出 SecurityException(在当前线程中)。 参数: on - 如果为 true,则将该线程标记为守护线程。

示例如下:

package com.example.thread.one;  
  
public class ThreadDemo {  
    public static void main(String[] args) {  
        MyThread mThread1 = new MyThread();  
        MyThread mThread2 = new MyThread();  
        //为线程设置名称  
        mThread1.setName("守护1");  
        mThread2.setName("守护2");  
        //将两个线程都设置为守护线程.这个设置必须在启动线程前调用。  
        mThread1.setDaemon(true);  
        mThread2.setDaemon(true);  
        //启动两个守护线程  
        mThread1.start();  
        mThread2.start();  
          
        //当前线程,也就是main线程,为守护线程  
        Thread.currentThread().setName("被守护的线程");  
        for (int i = 0; i < 5; i++) {  
            System.out.println(Thread.currentThread().getName() + " :" + i);  
        }  
    }  
}  
  
class MyThread extends Thread{  
    @Override  
    public void run() {  
        super.run();  
        for (int i = 0; i < 100; i++) {  
            System.out.println(getName() + " :" + i);  
        }  
    }  
}  

当被守护的线程执行完后,两个守护线程不会将循环执行完,而是随着被守护线程执行完成也终止循环。

1.5 终止线程(中断线程)

使用interrupt()方法来中断线程。该方法属于Thread对象的方法:

public void interrupt() 中断线程。

如果当前线程没有中断它自己(这在任何情况下都是允许的),则该线程的 checkAccess 方法就会被调用,这可能抛出 SecurityException。

如果线程在调用 Object 类的 wait()、wait(long) 或 wait(long, int) 方法,或者该类的 join()、join(long)、join(long, int)、sleep(long) 或 sleep(long, int) 方法过程中受阻,则其中断状态将被清除,它还将收到一个 InterruptedException。 如果该线程在可中断的通道上的 I/O 操作中受阻,则该通道将被关闭,该线程的中断状态将被设置并且该线程将收到一个 ClosedByInterruptException。 如果该线程在一个 Selector 中受阻,则该线程的中断状态将被设置,它将立即从选择操作返回,并可能带有一个非零值,就好像调用了选择器的 wakeup 方法一样。 如果以前的条件都没有保存,则该线程的中断状态将被设置。 中断一个不处于活动状态的线程不需要任何作用。 抛出: SecurityException - 如果当前线程无法修改该线程 public boolean isInterrupted() 测试线程是否已经中断。线程的中断状态 不受该方法的影响。 线程中断被忽略,因为在中断时不处于活动状态的线程将由此返回 false 的方法反映出来。 返回: 如果该线程已经中断,则返回 true;否则返回 false。

1.6 其他常用方法

public static Thread currentThread()
返回对当前正在执行的线程对象的引用。 
返回:
当前执行的线程。
public final String getName()
返回该线程的名称。 
返回:
该线程的名称。
public final void setName(String name)
改变线程名称,使之与参数 name 相同。 
首先调用线程的 checkAccess 方法,且不带任何参数。这可能抛出 SecurityException 
参数:
name - 该线程的新名称。 
抛出: 
SecurityException - 如果当前线程不能修改该线程。
public final int getPriority()
返回线程的优先级。 
返回:
该线程的优先级。
public final void setPriority(int newPriority)
更改线程的优先级。未设置时默认为5.
首先调用线程的 checkAccess 方法,且不带任何参数。这可能抛出 SecurityException 
在其他情况下,线程优先级被设定为指定的 newPriority 和该线程的线程组的最大允许优先级相比较小的一个。 
参数:
newPriority - 要为线程设定的优先级 
抛出: 
IllegalArgumentException - 如果优先级不在 MIN_PRIORITY(1)  MAX_PRIORITY(10) 范围内。 
SecurityException - 如果当前线程无法修改该线程。
public final ThreadGroup getThreadGroup()
返回该线程所属的线程组。 如果该线程已经终止(停止运行),该方法则返回 null 
public final boolean isAlive()
测试线程是否处于活动状态。如果线程已经启动且尚未终止,则为活动状态。 
返回:
如果该线程处于活动状态,则返回 true;否则返回 false
public String toString()
返回该线程的字符串表示形式,包括线程名称、优先级和线程组。 
覆盖:
 Object 中的 toString
返回:
该线程的字符串表示形式。
最近的文章

Java使用同步解决线程安全问题的弊端及带来的问题

1 多线程使用同步解决方案引入的问题由于多线程会引入线程安全问题,我们使用了同步或者加锁的方法来解决这个问题,但是使用同步的方法也会带来相应的弊端。主要有如下两个弊端: 使用同步的方法效率低 如果出现同步嵌套,会出现死锁问题。对于第一个问题,告诉我们要慎用同步,只在必要的位置添加同步方法,而不是为了安全添加不必要的同步,这样会导致效率的降低,因为如果使用了同步会有锁机制,执行相关代码前会对锁进行相应的检查,这样就会降低效率。第二个问题是主要讲解的问题,这个我们需要在程序中尽量避免,如果...…

继续阅读
更早的文章

Java多线程安全典型案例

1 问题引入通过最常见的多窗口售票问题引入线程安全的问题。注:这里使用Runnable接口来实现线程,这样做是为了共享代售票这个资源,如果我们使用继承Thread来操作,需要将代售票ticketCount设置为全局的公共变量才能实现效果。代码如下:package com.example.thread.one; public class ThreadDemo { public static void main(String[] args) { SellTic...…

继续阅读