Java多线程基础

进程和线程

进程:正在运行的程序实例,是资源分配的基本单位。例如我打开了英雄联盟 lol.exe,就启动了一个进程。

多进程:在我启动 lol.exe 之后,又打开了一个 dota.exe,即多个程序在同时运行。

线程:线程是进程的一部分,是调度和执行的基本单位,属于进程的一部分。例如在 lol.exe 这个进程中,盖伦攻击亚索就是一个线程实现的。

多线程:在同一时刻,盖伦攻击亚索,同时辛德拉在攻击盲僧,那么这就属于多线程。即一个进程中,多个相互独立或相互有协作关系的运行单元就是多线程。

三种线程创建方法

1. 继承Thread类

设计一个类,继承线程父类Thread,同时在这个类的内部重写run方法。看下面一段代码:

	public static class MyThread extends Thread{
		int num;
		int id;
		
		public MyThread(int num, int id) {
			this.num = num;
			this.id = id;
		}
		
		public void run() {
			while(num > 0) {
				System.out.println(this.id + " : " + this.num--);
			}
		}
	}

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		MyThread thread1 = new MyThread(100, 1);
		thread1.start();
		MyThread thread2 = new MyThread(100, 2);
		thread2.start();
	}

在上面的代码中,我们创建了MyThread类,继承Thread类并重写了run方法。在main函数中,实例化了两个MyThread的对象,调用多个start方法即可启动多个线程。

2. 实现Runnable接口

设计一个类MyThread,让它实现Runnable接口,重写里面的run方法。在调用的时候,先创建一个类MyThread的对象,再创建一个Thread对象,并把MyThread的对象作为构造方法的参数传给Thread。看一段代码:

	public static class MyThread implements Runnable{
		int num;
		int id;
		
		public MyThread(int num, int id) {
			this.num = num;
			this.id = id;
		}
		
		public void run() {
			while(num > 0) {
				System.out.println(id + " : " + num--);
			}
		}
	}

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		MyThread thread1 = new MyThread(100, 1);
		Thread t1 = new Thread(thread1);
		
		MyThread thread2 = new MyThread(100, 2);
		Thread t2 = new Thread(thread2);
		
		t1.start();
		t2.start();
	}

上面的代码比较简单,值得注意的是由于MyThread类实现了Runnable接口,因此他有run方法,并且需要重写。实例化MyThread得到了对象thread1,它要作为构造方法的参数传递到new的Thread中,最后调用start即可启动线程。

3. 匿名内部类
	Thread t1 = new Thread() {
			int id = 1;
			int num = 100;
			public void run() {
				while(num > 0) {
					System.out.println(id + " : " + num);
					num--;
				}
			}
		};

在创建一个Thread对象的后面跟上大括号,大括号中重写run方法,比较容易理解。

常见线程方法

1. sleep

sleep方法是让当前的线程暂停,sleep(1000)代表暂停1000毫秒。下面看一段代码:

	Thread t1 = new Thread() {
		int id = 1;
		int num = 100;
		public void run() {
		while(num > 0) {
			System.out.println(id + " : " + num);
			if(num == 70) {
				try {
					Thread.sleep(1000);
				}catch(InterruptedException e) {
					e.printStackTrace();
				}
			}
			num--;
		}
	};

这段代码表示创建一个线程t1,在成员num为70的时候,该线程休眠1秒。注意,sleep可能会抛出InterruptedException 中断异常,因此需要在try-catch块中运行。

2. join

join是将当前线程添加到主线程中。那么什么是主线程呢?

对于所有的进程,至少有一个线程为主线程,那么在main函数开始执行的时候,就有一个看不见摸不着的主线程存在了。

那么通过join方法,就可以将当前线程加入到主线程,即主线程需要等待该线程运行结束,才能往下运行。

看一下下面的代码:

	Thread t1 = new Thread() {
		int id = 1;
		int num = 100;
		public void run() {
			while(num > 0) {
				System.out.println(id + " : " + num);
				num--;
			}
		}
	};
	t1.start();
	
	//将t1加入主线程
	try {
		t1.join();
	}catch (Exception e) {
		e.printStackTrace();
	}
	
	Thread t2 = new Thread() {
		int id = 2;
		int num = 100;
		public void run() {
			while(num > 0) {
				System.out.println(id + " : " + num);
				if(num == 70) {
				//yield表示暂停线程,让其他线程获得更多CPU资源
					Thread.yield();
				}
				num--;
			}
			
		}
	};
	t2.start();

在代码的中间,我们通过调用join方法,将线程t1加入了主线程。因此需要将t1线程运行完才能接着去运行下面的t2线程。

3. setPriority

给线程设置优先级,优先级越高越容易得到CPU资源,其中最高的优先级为MAX_PRIORITY,最低的为MIN_PRIORITY。

4. setDaemon

将线程设置为守护线程。

Java中存在两种线程,即守护线程和用户线程(非守护线程),之前所说的都是用户线程。当进程中所有的用户线程都消失的时候,守护线程也跟着销毁,当前进程结束。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值