线程的状态、调度、同步

线程的状态

  • java中的线程共五个状态:新建、就绪、运行、阻塞、死亡

在这里插入图片描述

  1. 新建状态(New):处于系统创建线程,但未启动此线程,系统未为其分配资源。
  2. 就绪状态(Runnable):线程调用start( )方法,线程转为就绪状态,线程获取(除CPU以外)系统资源。同时该线程位于可运行线程池中,变得可运行,等待调度程序调度。
  3. 运行状态(Running):线程获得CPU时间,进入运行状态,开始执run()方法。
  4. 阻塞状态(Blocked):系统让出CPU进入阻塞状态,可根据特定的方法返回可运行状态。
  5. 死亡状态(Dead):线程执行完毕或异常退出run( )方法,线程结束生命周期。

线程的调度

  • 在多个CPU的计算机中,线程数多余CPU的个数,为了防止因线程争夺资源,而导致系统死机或崩溃,Java中定义了线程的优先级控制调整策略

  • 优先级控制: Java将优先级分为10个等级,数字越大优先级越高。静态常量MIN_PRIORITY、NORMAL_PRIORITY、MAX_PRIORITY;

    • void setPriority(int newPriority):设置(改变)线程的优先级。
    • int getPriority():得到线程的优先级。
  • 线程的调度策略:
    1.分时调度模型:线程轮流获取cpu的使用权,采用时间片均匀分配的方式。
    2.抢占式调度模型:以优先级高的线程占用CPU为标准,直至线程自己放弃。
    注:Java虚拟机采用抢占式调度模型

  • 参考代码:

public class PriorityTest {

	
	public static void main(String[] args){
		
		PriorityTestThree r = new PriorityTestThree();
		Thread testOne = new Thread(r,"线程1");
		
		// 设置优先级
		testOne.setPriority(Thread.NORM_PRIORITY - 2);
		testOne.start();
		
		Thread testTwo = new Thread(r,"线程2");
		// 设置优先级
		testTwo.setPriority(Thread.NORM_PRIORITY + 2);
		testTwo.start();
	}	

	static class PriorityTestThree implements Runnable{

		public void run() {
			// TODO Auto-generated method stub
			
			for(int i = 0; i<4;i++){
				
				System.out.println(Thread.currentThread().getName() + ":" +i);
				
			}
			
			System.out.println(Thread.currentThread().getName() + ":完成!");
		}
	}
	
}

  • 控制台输出结果:
线程20
线程21
线程22
线程23
线程10
线程2:完成!
线程11
线程12
线程13
线程1:完成!


线程的同步

  • 线程同步: 指当一个临界资源被线程访问时,其它线程不能对该资源访问;直至该线程访问结束,其他线程才方可访问该临界资源。

  • 适用场景: 一些敏感资源不能被多个线程临时访问时,适用同步访问技术,来保障数据的安全性和准确性。

  • 同步化的两种方法: 同步方法和同步代码块。

    1. 同步方法:使用synchronized关键字修饰需要同步的方法。该方法会自动被加上内置锁。
      		public synchronized 类型 方法名(参数表) {	// 方法体	}
      
    2. 同步代码块:即用synchronzied关键字修饰的语句块,该语句块会自动被加上内置锁。
      		synchronize (object){	// 语句块	}
      
  • 以银行存款为例:

    • 参考代码:
public class BankThreadTest implements Runnable {

	private static Bank bank;
	BankThreadTest(Bank bank){		
		this.bank = bank;
	}
	
	public void run(){
		for(int i=0;i<3;i++){
			bank.save(100);
		}
	}
	
	public static void main(String[] args){
		
		bank = new Bank();
		
		BankThreadTest s = new BankThreadTest(bank);
		
		Thread threadOne = new Thread(s);
		threadOne.start();
		
		Thread threadTwo = new Thread(s);
		threadTwo.start();
	}
	
	static class Bank{
		
		private int money = 0;
		 //  设置同步方法
		public synchronized void save(int money){
			int temp = this.money;
			temp += money;
			
			try{
				// 设置休眠时间
				Thread.sleep((int)(Math.random()*1000));
				}catch(InterruptedException e){
				e.printStackTrace();
			}
			
			this.money = temp;
			String n = Thread.currentThread().getName();
			System.out.println(n + ":存入"+ money + "元,账户余额为:"+ this.money);
		
	}
  }
}
  • 控制台输出结果:
Thread-0:存入100元,账户余额为:100
Thread-0:存入100元,账户余额为:200
Thread-0:存入100元,账户余额为:300
Thread-1:存入100元,账户余额为:400
Thread-1:存入100元,账户余额为:500
Thread-1:存入100元,账户余额为:600
  • 不使用synchronized方法下的代码:
public class BankThreadTest implements Runnable {

	private static Bank bank;
	BankThreadTest(Bank bank){
		
		this.bank = bank;
	}
	
	public void run(){
		for(int i=0;i<3;i++){
			bank.save(100);
		}
	}
	
	public static void main(String[] args){
		
		bank = new Bank();
		
		BankThreadTest s = new BankThreadTest(bank);
		
		Thread threadOne = new Thread(s);
		threadOne.start();
		
		Thread threadTwo = new Thread(s);
		threadTwo.start();
	}
	
	static class Bank{
		
		private int money = 0;
		
		public void save(int money){
			//synchronized
			int temp = this.money;
			temp += money;
			
			try{
				Thread.sleep((int)(Math.random()*1000));
				}catch(InterruptedException e){
				e.printStackTrace();
			}
			
			this.money = temp;
			String n = Thread.currentThread().getName();
			System.out.println(n + ":存入"+ money + "元,账户余额为:"+ this.money);
		
	}
  }
}
  • 控制类输出结果:
Thread-1:存入100元,账户余额为:100
Thread-0:存入100元,账户余额为:100
Thread-1:存入100元,账户余额为:200
Thread-0:存入100元,账户余额为:200
Thread-1:存入100元,账户余额为:300
Thread-0:存入100元,账户余额为:300
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值