JAVA学习——多线程

多线程就是指一个应用程序中有多条并发执行的线索,每条线索都被称作一个线程,他们会交替执行。


在实现方式上,主要有两种:

1.继承Thread类

2.实现Runnable接口


继承Thread类

此处我们模拟窗口售票程序,以便为后面比较两种实现方式

/**
 * 模拟窗口售票
 *  继承Thread类,实现多线程,
 * @author Shawn·Zhang
 */

public class Example01 {

	public static void main(String[] args) {
		new TicketWindow().start();//创建一个线程对象TicketWindow并开启
		new TicketWindow().start();//创建一个线程对象TicketWindow并开启
	}
}

class TicketWindow extends Thread {
	private int tickets = 5;

	@Override
	public void run() {
		while (true) {//通过死循环打印
			if (tickets > 0) {
				System.out.println(Thread.currentThread().getName() + "正在发售第"
						+ tickets-- + "张票");
			}
		}
	}
}


测试结果如图:




实现Runnable接口

/**
 * 模拟窗口售票 
 * 实现Runnable接口,实现多线程,
 * @author Shawn·Zhang
 */

public class Example02 {

	public static void main(String[] args) {
		TicketWindow tw = new TicketWindow();//创建TicketWindow实例对象tw
		new Thread(tw).start();//创建线程,并开启
		new Thread(tw).start();//创建线程,并开启
	}
}

class TicketWindow implements Runnable {
	private int tickets = 5;

	@Override
	public void run() {
		while (true) {//通过死循环打印输出语句
			if (tickets > 0) {
				System.out.println(Thread.currentThread().getName() + "正在发售第"
						+ tickets-- + "张票");
			}
		}
	}
}

测试结果如图:



从运行结果可以看出,继承Thread类时,每张票都被打印了2次,出现这种现象,说明2个线程没有共享5张票,而是各自出了5张

从代码也可以看出,继承Thread类时,创建了两个TicketsWindow对象,每个线程各自独立运行,互不干扰

实现Runnable接口,只创建了一个TicketsWindow对象,然后创建两个线程,每个线程在调用时,都去调用TicketsWindow对象的run()方法,这样就可以保证线程在访问的时候是同一个tickets变量,共享5张票


实现Runnable接口相比较继承Thread类的优势:

1、适合多个线程处理同一资源

2、可以避免java的单继承


PS:大部分应用程序在设计的时候,大多采用第二种方式来创建多线程,即实现Runnable接口


后台线程

对java程序来说,只要还有一个前台线程在运行,这个进程就不会结束,如果一个进程中只有后台线程运行,这个进程就会结束。

调用setDaemon(true)方法,使线程变成一个后台线程

/**
 * 后台线程
 * @author Shawn·Zhang
 *
 */

public class Example03 {

	public static void main(String[] args) {
		DaemonThread dt = new DaemonThread();//创建dt对象,并实例化
		Thread t = new Thread(dt,"t线程");//创建线程t,并共享dt资源
		System.out.println("t线程默认是后台线程吗?"+Thread.currentThread().isDaemon());//判断是否默认后台线程
		t.setDaemon(true);//将t线程设置为后台线程
		t.start();//启动线程
	}

}

class DaemonThread implements Runnable{//创建DaemonThread类,实现runnable接口
	@Override
	public void run() {//重写run()方法
		System.out.println(Thread.currentThread().getName()+"正在运行");
	}
}
从结果可以看出,虽然是死循环,但程序还是可以运行完毕,这是因为操作的线程已经是后台线程了

注意:将线程设置为后台线程,一定要在未启动之前设置,也就是说setDaemon(true)方法要在start()方法前调用,否则会出现java.lang.IllegalThreadStateException异常


线程的优先级

通过Thread类的setPriority(int newPriority)方法对其进行设置,该方法的参数newPriority接收的是1~10的整数,或三个Thread类的静态常量。

Thread类的静态常量功能描述
static int MAX_PRIORITY表示线程的最高优先级,相当于值10
static int MIN_PRIORITY表示线程的最低优先级,相当于值1
static int NORM_PRIORITY表示线程的普通优先级,相当于值5

线程的休眠

可以人为的控制线程,使正在执行的线程暂停,将CPU让给其它线程。

调用静态方法sleep(long millis)

/**
 * 线程休眠
 * @author Shawn·Zhang
 */

public class Example04 {

	public static void main(String[] args) throws Exception {
		new Thread(new SleepThread()).start();//创建线程
		
	}
}

class SleepThread implements Runnable {
	@Override
	public void run() {
		for (int i = 1; i <= 5; i++) {
				try {
					Thread.sleep(2000);//当前线程休眠2秒
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			System.out.println("线程一正在输出:" + i);
		}
	}
}


测试结果为:每隔2秒输出一行

线程一正在输出:1
线程一正在输出:2
线程一正在输出:3
线程一正在输出:4
线程一正在输出:5


线程插队

在现实生活中,经常会遇到插队的现象,而在Thread里面,也提供了一个join()方法来实现这个“功能”。

在调用join()方法的线程要执行完之后,其他进程才能继续执行。

/**
 * 线程插队
 * @author Shawn·Zhang
 */

public class Example05 {
	public static void main(String[] args) throws Exception {
		Thread t = new Thread(new MyThread(), "线程一");
		t.start();
		for (int i = 0; i < 5; i++) {
			System.out.println(Thread.currentThread().getName() + "正在输出:" + i);
			if (i == 2) {
				t.join();
			}
			Thread.sleep(500);
		}
	}
}

class MyThread implements Runnable {
	@Override
	public void run() {
		for (int i = 0; i < 5; i++) {
			System.out.println(Thread.currentThread().getName() + "正在输出:" + i);
			try {
				Thread.sleep(500);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
}
执行结果如下:

main正在输出:0
线程一正在输出:0
线程一正在输出:1
main正在输出:1
main正在输出:2
线程一正在输出:2
线程一正在输出:3
线程一正在输出:4
main正在输出:3
main正在输出:4


线程的同步:

传送门:http://blog.csdn.net/u012482299/article/details/48226661

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值