多线程

1.线程和进程的区别

1.线程是程序执行的最小单位,而进程是操作系统分配资源的最小单位
2.一个进程由一个或多个线程组成,线程是一个进程中代码的不同执行路线
3.进程之间相互独立,但同一进程下的各个线程之间共享程序的内存空间(包括代码段、数据集、堆等)及一些进程级的资源(如打开文件和信号等),某进程内的线程在其他线程不可见
4.调度和切换:线程上下文切换比进程上下文切换要快得多
一个线程的生命周期分为:创建、就绪、运行、阻塞、死亡

2.线程的创建

2.1 继承Thread类

线程的创建方式1:继承Thread类 重写run方法

public class T1 extends Thread{
	@Override
	public void run() {
		System.out.println(Thread.currentThread().getName());
	}
	
	public static void main(String[] args) {
		T1 t1 = new T1();
		t1.setName("线程A");
		t1.start(); // 调用start方法才会开启新的线程 
//		t1.run(); 调用run方法不会开启新的线程 依然使用main线程调用run方法
	}
}

2.2 实现Runnable接口

创建线程方式2 :实现Runnable接口 重写run方法

public class T2 implements Runnable{
	@Override
	public void run() {
		System.out.println(Thread.currentThread().getName());
	}
	
	public static void main(String[] args) {
		T2 t2 = new T2();
		Thread thread = new Thread(t2, "线程A");
		thread.start();
	}
}

2.3 两种方式对比

继承Thread类:
编写简单,可直接操作线程
适用于单继承

实现Runnable接口:
避免单继承局限性
便于共享资源
推荐使用实现Runnable接口方式创建线程

3.线程的基本方法

3.1 线程的优先级

设置优先级的方法:setPriority();
获取优先级的方法:getPriority();
线程的优先级 默认为5 最低为1 最高为10
优先级高代表获取CPU资源的概率较大 并不能保证一定会优先获得CPU资源
MAX_PRIORITY 最高10
MIN_PRIORITY 最低1
NORM_PRIORITY 默认5

public class T1 extends Thread{
	@Override
	public void run() {
		for (int i = 0; i < 10; i++) {
			System.out.println(Thread.currentThread().getName() + i);
		}
	}
	
	public static void main(String[] args) {
		T1 thread1 = new T1();
		thread1.setName("赵四");
		T1 thread2 = new T1();
		thread2.setName("广坤");
		
		System.out.println(thread1.getPriority()); 
		System.out.println(thread2.getPriority());
		
		thread1.setPriority(Thread.MAX_PRIORITY); // 设置优先级为最高  10
		thread2.setPriority(1);// 设置优先级为最低 1

		thread1.start();
		thread2.start();	
	}
}

3.2 线程的休眠

线程休眠的方法 sleep(long mills)

3.3 线程的插队

方法为:join() 等待插队线程执行完毕 再执行当前线程
join(long mills) 等待插队线程固定时间 时间结束就执行当前线程

3.4 线程的礼让

yield()方法 线程礼让 当前线程礼让其他线程 让其他线程先执行
只是提供一种可能 不一定会礼让

3.5 线程的中断

interrupt() 中断线程方法 但不是立即中断 如果当前线程有未执行完的任务 将执行完毕再中断
interrupted() 查看当前线程是否可以被中断 返回为true或false
stop() 为立即中断线程的方法(已弃用)

4.线程安全

处理多线程共享数据引发的问题

4.1 编写购票系统

编写一个购票系统,使用同步代码块实现三个人可以轮流买票

public class T4 implements Runnable{
	int count = 10;
	@Override
	public void run() {
		while(true ) {
			try {
				Thread.sleep(500);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			synchronized(this) {
				if(count == 0) {
					break;
				}
				count--;
				System.out.println(Thread.currentThread().getName() + "抢到了第"+ (10 - count)+" 张票,还剩余" + count + "张票");
			}
		}
		// 后续代码
	}
	
	public static void main(String[] args) {
		T4 t3 = new T4();
		Thread zhaosi = new Thread(t3, "赵四");
		Thread guangkun = new Thread(t3, "广坤");
		Thread dana = new Thread(t3, "大拿");
		
		zhaosi.start();
		guangkun.start();
		dana.start();	
	}
}

使用同步方法实现

public class T5 implements Runnable{
	int count = 10;
	@Override
	public synchronized void run() {
		while(count > 0) {
			try {
				Thread.sleep(500);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			count--;
			System.out.println(Thread.currentThread().getName() + "抢到了第"+ (10 - count)+" 张票,还剩余" + count + "张票");	
		}
	// 后续代码
}

public static void main(String[] args) {
	T5 t3 = new T5();
	Thread zhaosi = new Thread(t3, "赵四");
	Thread guangkun = new Thread(t3, "广坤");
	Thread dana = new Thread(t3, "大拿");

	zhaosi.start();
	guangkun.start();
	dana.start();

}
}

4.2 synchronized关键字规则

同一时刻只能有一个线程进入synchronized(this)同步代码块
当一个线程访问一个synchronized(this)同步代码块时,其他synchronized(this)同步代码块同样被锁定
当一个线程访问一个synchronized(this)同步代码块时,其他线程可以访问该资源的非synchronized(this)同步代码

posted @ 2021-07-28 21:48  you_rgb  阅读(66)  评论(0)    收藏  举报
//一下两个链接最好自己保存下来,再上传到自己的博客园的“文件”选项中