JAVA 多线程【二】

本文详细介绍了Java线程的五种状态,包括创建、就绪、阻塞、运行和死亡,并讲解了线程调度的方法如setPriority、sleep、join、yield和interrupt。接着,讨论了线程安全的两种类型,同步方法和同步代码块,通过模拟网络抢票的例子展示了如何避免线程并发问题。同步机制确保了多线程环境下的数据一致性,防止资源竞争导致的问题。
摘要由CSDN通过智能技术生成

线程的状态

创建状态、就绪状态、阻塞状态、运行状态、死亡状态 

 线程调度

线程调度是指按照特定机制为多个线程分配CPU的使用权

方法                                                                作用 

setPriority(int  newPriority)                          更改线程的优先级

sleep(long millis)                                           在指定的毫秒数内让当前正在执行的线程休眠

join()                                                                强制执行

yield()                                                              线程礼让,给其他线程获得CPU资源的机会

interrupt()                                                       中断线程

isAlive()                                                           测试线程是否处于活动状态 

注意:

1、线程优先级高的线程获得CPU资源的概率较大,但不是一定(优先级从低到高:1~10)

2、线程礼让只是提供一种可能,不能保证一定会实现礼让

线程安全的类型

线程安全:方法同步,效率较低,适用多线程并发共享资源

非线程安全:方法不同步,效率高,适用单线程

线程安全类会使用synchronized 修饰方法或代码块

同步方法

语法:访问修饰符 synchronized 返回类型 方法名(参数列表){……}

 同步代码块

          语法:  synchronized (this) {   //同步代码块}

 案例

模拟网络抢票

1、不使用同步:当第一个线程运行到休眠时第二个线程获得CPU资源对数据进行更改,所以第一个线程休眠结束后输出的结果就改变了,导致同一张票由两个人或三个人同时抢到

public class Piao implements Runnable {
	// 声明一个变量用来表示票库中票的数据
	public int num = 10;
	// 声明一个变量用来表示用户抢到了第几张票
	public int count = 0;

	@Override
	public void run() {
		// 实现抢票行为:修改票库里的票的数目和显示用户抢到了第几张票
		while (true) {
			// 当票库里的票<0的时候,不再进行循环
			if (num <= 0) {
				break;
			}

			num--;
			count++;
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			System.out.println(Thread.currentThread().getName() + "抢到了第"
					+ count + "张票,还剩下" + num + "张票");

		}

	}

}

2、同步方法:当第一个线程抢到CPU资源时,整个方法会被锁死,第二个线程进不来必须等待第一个线程运行结束才能进来。

public class Piao implements Runnable {
	// 声明一个变量用来表示票库中票的数据
	public int num = 10;
	// 声明一个变量用来表示用户抢到了第几张票
	public int count = 0;
	public boolean flag =false;

	@Override
	public void run() {
		while (!flag) {
			sale();
		}
	}

	public synchronized void sale() {

		// 当票库里的票<0的时候,不再进行循环
		if (num <= 0) {
			flag = true;
			return;
		}

		num--;
		count++;
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		System.out.println(Thread.currentThread().getName() + "抢到了第" + count
				+ "张票,还剩下" + num + "张票");

	}

}

3、同步代码块

public class Piao implements Runnable {
	// 声明一个变量用来表示票库中票的数据
	public int num = 10;
	// 声明一个变量用来表示用户抢到了第几张票
	public int count = 0;

	@Override
	public void run() {
		while (true) {
			synchronized (this) {

				// 当票库里的票<0的时候,不再进行循环
				if (num <= 0) {
					break;
				}

				num--;
				count++;
				try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				System.out.println(Thread.currentThread().getName() + "抢到了第"
						+ count + "张票,还剩下" + num + "张票");

			}
		}
	}

}

4、测试类

public class Test {

	public static void main(String[] args) {
		Piao p = new Piao();
		Thread t1 = new Thread(p, "张三");
		Thread t2 = new Thread(p, "李四");
		Thread t3 = new Thread(p, "如花");

		t1.start();
		t2.start();
		t3.start();

	}

}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值