现在的位置: 首页 > 综合 > 正文

【重磅出击】 java入门到精通——多线程(中)

2013年04月27日 ⁄ 综合 ⁄ 共 2922字 ⁄ 字号 评论关闭

Java 多线程(中)

    在 《【重磅出击】 java入门到精通——多线程(上)》中,详细讲解了线程与进程,创建线程的两种方法,和线程的生命周期。这里我们讲解一些控制线程的方法。

控制线程之join

    join方法:调用join方法的线程对象强制运行,该线程强制运行期间,其他线程无法运行,必须等到该线程结束后其他线程才可以运行,有人也把这种方式成为联合线程。

代码如下:

public class JoinDemo {
	public static void main(String[] args) throws Exception {
		Thread join = new Thread(new Join(),"Join线程");
		join.start();		
		int i = 0;
		while(i < 500){
			if(i == 100){
				join.join();
			}
			System.out.println("Main -- > " + i ++);
		}
	}
}
class Join implements Runnable {
	public void run() {
		int i = 0;
		while(i< 200){
			System.out.println(Thread.currentThread().getName() + "--" + i ++ );
		}
	}
}

控制线程之Daemon

    后台线程:处于后台运行,任务是为其他线程提供服务。也称为“守护线程”或“精灵线程”。JVM的垃圾回收就是典型的后台线程。

    特点:若所有的前台线程都死亡,后台线程自动死亡。

    设置后台线程:Thread对象setDaemon(true);

   
setDaemon(true)必须在start()调用前
,否则出现IllegalThreadStateException异常;

前台线程创建的线程默认是前台线程;判断是否是后台线程:使用Thread对象的isDaemon()方法;

并且当且仅当创建线程是后台线程时,新线程才是后台线程。

代码如下:

class Daemon extends Thread {
	public void run() {
		for (int i = 0; i < 10000; i++) {
			System.out.println(getName() + "-" + i);
		}
	}
}
public class DaemonDemo {
	public static void main(String[] args) {
		Daemon d = new Daemon();
		d.setDaemon(true);//把 d  线程设置成后台线程
		d.start();
		for (int i = 0; i < 5; i++) {
			System.out.println(Thread.currentThread().getName()+"--" + i);
		}
	}
}

控制线程之sleep

线程休眠:

    让执行的线程暂停一段时间,进入阻塞状态,注意此方法会抛出异常。

    sleep(long milllis) throws InterruptedException:毫秒

    调用sleep()后,在指定时间段之内,该线程不会获得执行的机会。

代码如下:

public class SleepDemo {
	public static void main(String[] args) {
		for (int i = 10; i > 0; i--) {
			System.out.println("还剩" + i);
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
}

控制线程之优先级

   
每个线程都有优先级,优先级的高低只和线程获得执行机会的次数多少有关并非线程优先级越高的就一定先执行,哪个线程的先运行取决于CPU的调度; 默认情况下main线程具有普通的优先级,而它创建的线程也具有普通优先级

Thread对象的setPriority(int x)和getPriority()来设置和获得优先级。

MAX_PRIORITY : 值是10

MIN_PRIORITY : 值是1

NORM_PRIORITY : 值是5(主方法默认优先级)

代码如下:

class Priority extends Thread{
	public void run() {
		for (int i = 0; i < 100; i++) {
			System.out.println(getName()+",优先级=" + getPriority() +"--"+ i);
		}
	}
}
public class PriorityDemo {
	public static void main(String[] args) {
		Thread.currentThread().setPriority(7);
		for (int i = 0; i < 100; i++) {
			if(i == 10){
				Priority p1 = new Priority();
				p1.setPriority(Thread.MAX_PRIORITY);
				p1.start();
			}
			if(i == 15){
				Priority p2 = new Priority();
				p2.setPriority(Thread.MIN_PRIORITY);
				p2.start();
			}
			System.out.println("main" + i);
		}
	}
}

控制线程之yield

线程礼让:

暂停当前正在执行的线程对象,并执行其他线程;

Thread的静态方法,可以是当前线程暂停,但是不会阻塞该线程,而是进入就绪状态。所以完全有可能:某个线程调用了yield()之后,线程调度器又把他调度出来重新执行。

代码如下:

class Yield implements Runnable {
	public void run() {
		for (int i = 0; i < 100; i++) {
			System.out.println(Thread.currentThread().getName() + "--> " + i);
			if (i % 2 == 0) {
				Thread.yield();// 礼让
			}
		}
	}
}

public class YieldDemo {
	public static void main(String[] args) {
		Yield y = new Yield();
		new Thread(y, "A").start();
		new Thread(y, "C").start();
	}
}

控制线程之结束线程

   我们使用一个boolean型变量来控制线程的结束。
boolean flag = true;//用变量来控制线程
	public void run() {
		int i = 0;
		while (flag) {
			if (i == 25) {
				flag = false;
			}
			System.out.println("==" + i);
			i++;
		}
	}

   API过时方法--易死锁,不推荐使用

   stop:终止线程

   马上让线程停止运行,并释放该线程所持有的锁,该操作无法保证对象的内部状态正确;

   suspend:挂起线程

   使线程进入“阻塞”状态,该状态下CPU不会分给线程时间片,进入这个状态可以用来暂停一个线程的运行,在被resume方法调用前,不可用.

如果要suspend的目标线程对一个重要的系统资源持有锁,那么没任何线程可以使用这个资源直到要suspend的目标线程被resumed。 

resume:恢复线程

    恢复被suspend方法挂起的线程

抱歉!评论已关闭.