线程间的通信和线程调度(传智播客)

本文介绍了Java中线程间通信的方式,包括wait、notify、notifyAll以及JDK5.0引入的Lock和Condition接口。同时,文章讨论了线程调度的重要性,详细讲解了分时调度和抢占式调度模型,以及线程的优先级、休眠、让步和插队等概念,帮助理解Java线程的执行管理。
摘要由CSDN通过智能技术生成

一.线程间的通信
1.多个线程操作共享资源,但是任务不一样

class Resource{
	private int num = 1;
	private boolean flag = false;
	private String name;
	public synchronized void set(String name){
		if(flag){
			try{
				this.wait();
			}catch(InterruptedException e){
				
			}
		}
		this.name = name+num;
		System.out.println(Thread.currentThread().getName()+"生产了"+this.name);
		num++;
		this.flag = true;
		this.notify();
	}
	
	public synchronized  void out(){
		if(!flag){
			try{
				this.wait();
			}catch(InterruptedException e){
				
			}
		}
		System.out.println(Thread.currentThread().getName()+"消费了............"+this.name);
		this.flag = false;
		this.notify();
	}
}

class Producer implements Runnable{
	Resource r;
	
	public Producer(Resource r) {
		this.r = r;
	}

	@Override
	public void run() {
		while(true){
			r.set("烤鸭");
		}
	}
}

public class Consumer implements Runnable{
	Resource r;
	
	public Consumer(Resource r) {
		this.r = r;
	}

	@Override
	public void run() {
		while(true){
			r.out();
		}
	}
}

public class MyThread {

	public static void main(String[] args) {
		Resource r = new Resource();
		Producer pro = new Producer(r);
		Consumer con = new Consumer(r);
		Thread t0 = new Thread(pro);
		Thread t1 = new Thread(pro);
		Thread t2 = new Thread(con);
		Thread t3 = new Thread(con);
		t0.start();
		t1.start();
		t2.start();
		t3.start();
	}
}

wait、notify、notifyAll这些方法必须定义在同步中,因为这些方法是用来监视线程状态的,并且需要明确是哪一个锁上的线程。

2.jdk5.0

class Resourse{
	private String name;
	private int nums = 1;
	private boolean flag = false;
	ReentrantLock lock = new ReentrantLock();
	Condition pro = lock.newCondition();
	Condition con = lock.newCondition();
	public void set(String name){
		lock.lock();
		try{
			while(flag){
				try{
					pro.await();
				}catch(InterruptedException e){
					
				}
			}
			this.name = name+nums;
			nums++;
			System.out.println(Thread.currentThread().getName()+"生产了"+this.name);
			flag = true;
			con.signal();
		}finally{
			lock.unlock();
		}
	}
	
	public void out(){
		lock.lock();
		try{
			while(!flag){
				try{
					con.await();
				}catch(InterruptedException e){
					
				}
			}
			System.out.println(Thread.currentThread().getName()+"......消费了烤鸭......"+this.name);
			flag = false;
			pro.signal();
		}finally{
			lock.unlock();
		}
	}
}

class Producer implements Runnable{
	Resourse r;

	public Producer(Resourse r) {
		this.r = r;
	}

	@Override
	public void run() {
		// TODO Auto-generated method stub
		while(true){
			r.set("烤鸭");
		}
	}
	
}

class Consumer implements Runnable{
	Resourse r;

	public Consumer(Resourse r) {
		this.r = r;
	}
	
	@Override
	public void run() {
		// TODO Auto-generated method stub
		while(true){
			r.out();
		}
	}
}
public class ProducerConsumer {

	public static void main(String[] args) {
		Resourse r = new Resourse();
		Producer p = new Producer(r);
		Consumer c = new Consumer(r);
		Thread t0 = new Thread(p);
		Thread t1 = new Thread(p);
		Thread t2 = new Thread(c);
		Thread t3 = new Thread(c);
		t0.start();
		t1.start();
		t2.start();
		t3.start();
	}
}

用Lock接口替代了同步关键字synchronized,将原来对获取锁,释放锁的操作(隐式)变为显示操作了。
用Condition接口替代了object的监视器方法,封装成了监视器对象,可以与任意锁进行组合。

二.线程调度
1.为什么使用
程序中的多个线程是并发执行的,在某个线程想要被执行就必须要获得cpu的执行权。jvm为线程分配cpu使用权的机制被称为线程的调度。
2.两种调度模型

  • 分时调度模型:平均分配cpu时间片段,让线程轮流执行
  • 抢占式调度模型:让线程优先级高的先运行,优先级相同的随机选择一个运行(java默认采用这种方式的调度模型)

3.线程优先级

public class MyThread implements Runnable{
	@Override
	public void run() {
		for(int i=0;i<100;i++){
			System.out.println(Thread.currentThread().getName()+"is inputing..."+i);
		}
	}
	
	public static void main(String[] args) {
		MyThread my = new MyThread();
		Thread t0 = new Thread(my);
		Thread t1 = new Thread(my);
		t0.setPriority(1);
		t0.setPriority(10);
		t0.start();
		t1.start();	
	}
}

用1-10来表示,10最高,可通过setPriority()来设置优先级,参数为1-10或者3个常量。

  • 1 Thread.MIN_PRIORITY
  • 5 Thread.NORM_PRIORITY
  • 10 Thread.MAX_PRIORITY

4.线程的休眠
通过调用Thread.sleep()方法来让当前线程暂停运行,释放cpu执行权和执行资格,让别的线程先运行。
休眠时间超时,线程就进入就绪状态,重新具备cpu执行资格,在就绪线程池中等待cpu执行权。
5.线程让步
和sleep方法功能类似,都是让出线程的cpu执行权,区别在于yeild方法不会让线程经过阻塞状态,而是直接进入就绪状态。

public class MyThread implements Runnable{
	@Override
	public void run() {
		for(int i=0;i<100;i++){
			System.out.println(Thread.currentThread().getName()+"......is inputing......"+i);
			if(i==10){
				System.out.println("线程让步");
				Thread.yield();
			}
		}
	}
	
	public static void main(String[] args) {
		MyThread my = new MyThread();
		Thread t0 = new Thread(my);
		Thread t1 = new Thread(my);
		t0.start();
		t1.start();
	}
}

6.线程插队
当正在运行的线程调用了其它线程的join方法时,调用者进入阻塞状态,当其它线程运行完毕,调用者进入就绪状态。

public class MyThread implements Runnable{
	@Override
	public void run() {
		for(int i=0;i<100;i++){
			System.out.println(Thread.currentThread().getName()+"......is inputing......"+i);
		}
	}
	
	public static void main(String[] args) throws InterruptedException {
		MyThread my = new MyThread();
		Thread t0 = new Thread(my);
		t0.start();
		for(int i=0;i<100;i++){
			System.out.println(Thread.currentThread().getName()+"......is inputing......"+i);
			if(i==10){
				System.out.println("线程插队");
				t0.join();
			}
		}
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值