Java进阶之多线程Thread、Runnable

进程:

是指一个内存中运行的应用程序,每个进程都有一个独立的内存空间,一个应用程序可以同时运行多个进程;进程也是程序的一次执行过程,是系统运行程序的基本单位;系统运行一个程序即是一个进程,从创建、运行到消亡的过程。

线程:

线程是进程中的一个执行单元,负责当前进程中程序的执行,一个进程至少有一个线程。一个进程中是可以有多个线程的,这个应用程序也成为多线程程序。

简而言之:一个程序运行后至少有一个进程,一个进程中可以包含多个线程。

线程调度:

  1. 分时调度
    所有线程轮流使用CPU的使用权,平均分配每个线程占用CPU的时间。

  2. 抢占式调度
    优先让优先级高的线程使用CPU,如果线程的优先级相同,那么会随机选择一个(线程随机性),Java使用的就是抢占式调度。

详解

实际上,CPU使用抢占式调度模式在多个线程间进行着高速的切换。对于CPU的一个核而言,某个时间,只能执行一个线程,而CPU的在多个线程间切换速度相对于我们的感觉要快,看上去就是在同一时刻运行。其实,多线程程序并不能提高程序的运行速度,但能够提高程序运行效率,让CPU使用率更高。

创建线程的两种方式以及常用的方法

// 实现Runnable接口
public class RunImpl implements Runnable{

    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            System.out.println("RunImpl-->"+i);
        }
    }
}

// 继承Thread类
public class MyThread extends Thread{
    
    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            System.out.println(currentThread().getName()+"-->"+i);
        }
    }
}

public class Review1 {
    public static void main(String[] args) {
        MyThread mt = new MyThread();
        new Thread(new RunImpl()).start();
        mt.start();
        for (int i = 0; i < 10; i++) {
            System.out.println("main-->"+i);
        }
    }
}

实现Runnable接口比继承Thread类所具有的优势:

  1. 适合多个相同的程序代码的线程去共享同一个资源;
  2. 可以避免java中的单继承的局限性(即继承了一个类则无法再继承第二个类,如果一开始写固定了,用了继承这种方式,则后续再向拓展就没办法了,而接口可以避免这一点);
  3. 增加程序的健壮性,实现解耦操作,代码可以被多个线程共享,代码和线程独立。(主要就是解耦,用了多态的形式,想切换到哪个线程,只要改变父类引用指向的子类对象即可);
  4. 线程池只能放入实现Runnable或者Callable类线程,不能直接放入继承Thread的类。

扩充:在Java中,每次程序运行至少启动两个线程。一个是main线程,一个是垃圾收集线程。

线程同步的三个方法

  1. 同步代码块
// synchronized关键字可以用于方法中的某个区块中,表示只对这个区块的资源实现互斥访问
	public class Ticket implements Runnable{
		private int ticket = 100;
		Object lock = new Object();/** 执行卖票操作*/
		@Override
		public void run() {
		//每个窗口卖票的操作
		//窗口 永远开启
		while(true){
			synchronized (lock) {
				if(ticket>0){
					//有票 可以卖
					//出票操作
					//使用sleep模拟一下出票时间
					try {
						Thread.sleep(50);
					} 
					catch (InterruptedException e) {	
						e.printStackTrace();
					}
				//获取当前线程对象的名字
	String name = Thread.currentThreaSystem.out.println(name+"正在卖:"+ticket--);
		}
	}
}
  1. 同步方法
public synchronized void sellTicket(){
	if(ticket>0){
		try {
			Thread.sleep(100);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		String name = Thread.currentThread().getName();
		System.out.println(name+"正在卖:"+ticket‐‐);
		}
	}

  1. 锁机制
	public class Ticket implements Runnable{
		private int ticket = 100;
		Lock reentrantLock = new ReentrantLock();
		@Override
		public void run() {
		//每个窗口卖票的操作
		//窗口 永远开启
		while(true){
			 reentrantLock.lock();
				if(ticket>0){
					//有票 可以卖
					//出票操作
					//使用sleep模拟一下出票时间
					try {
						Thread.sleep(50);
					} 
					catch (InterruptedException e) {
						e.printStackTrace();
					}
				//获取当前线程对象的名字
	String name = Thread.currentThreaSystem.out.println(name+"正在卖:"+ticket--);
		}
		reentrantLock.unlock();
		}
	}
}

下面说下几种线程状态
在这里插入图片描述
在这里插入图片描述
以上这些没必要死记硬背,理解就行,关键就是围绕着“锁”在竞争。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值