Java中的线程(三)(线程间通信、线程池)

一、线程间的通信

       针对同一个资源的操作有不同种类的线程,让不同的线程相互影响且不发生错乱,即我们常说的生产者消费者模式。

       生产者消费者问题,也称有限缓冲问题,是一个多线程同步问题的经典案例,该问题描述了两个共享固定大小缓冲区的线程——即生产者和消费者——在运行时会出现的问题。

        生产者的主要作用是生成一定量的数据放到缓冲区中,然后重复此过程,与此同时,消费者也在缓冲区消耗这些数据,该问题的关键就是要保证生产者不会在缓冲区满是加入数据,消费者也不会在缓冲区空时消耗数据。

        要解决该问题,就必须让生产者在缓冲区休眠(要么干脆放弃数据),等到下次消费者消耗缓冲区的数据的时候,生产者才能被唤醒,开始往缓冲区里添加数据,同样也可以让消费者在缓冲区空的时候,进入休眠,等到生产者开始往缓冲区里添加数据是,在唤醒消费者,通常用的方法有 信号灯法,管程等。

        通过设置线程(生产者)和获取线程(消费者)针对同一个学生对象进行操作。

        代码

public class Student {
	
	String name;
	int age;
	boolean flag=true;//信号灯法,用来标志是否已经录入信息

}
/**
 * wait();使线程进入等待状态————阻塞状态
 * notify();唤醒线程————就绪状态
 */

public class SetStudent implements Runnable {

	Student s = new Student();

	public SetStudent(Student s) {
		this.s = s;
	}

	@Override
	public void run() {
		while (true) {
			synchronized (s) {
				if(s.flag) {//代表学生信息已经录入,需要消费者消费
					try {
						s.wait();
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
				s.name="张三";
				s.age=17;
				
				s.flag=true;//修改标记
				s.notify();//唤醒因为s锁对象进入等待状态的线程---获取线程
			}
		}
	}
}
public class GetStudent implements Runnable {

	Student s= new Student();
	
	public GetStudent(Student s) {
		this.s=s;
	}
	
	@Override
	public void run() {
		while(true) {
			synchronized(s) {
				if(!s.flag) {
					try {
						s.wait();
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
				
				System.out.println(s.name  + ":" + s.age);
				
				s.flag = false;//修改标记
				s.notify();//唤醒因为s所对象进入等待状态的线程---设置线程
				
			}
		}
	}

}
/*
 * 	资源类:Student
 * 	设置线程:SetStudent
 * 	获取线程:GetStudent
 * 	测试类:StudentDemo
 * 
 */
public class StudentDemo {
	public static void main(String[] args) {
		Student s = new Student();
		SetStudent set = new SetStudent(s);
		GetStudent get = new GetStudent(s);

		Thread t1 = new Thread(set);
		Thread t2 = new Thread(get);

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

	}
}

二、线程池(补充)(摘抄)

    1、线程组

          Java中使用ThreadGroup来表示线程组,它可以对一批线程进行分类管理,Java允许程序直接对线程组进行控制。

          默认情况下,所有的线程都属于主线程组。

                public final ThreadGroup getThreadGroup()

          我们也可以给线程设置分组

                Thread(ThreadGroup group, Runnable target, String name)

    2、线程池

                程序启动一个新线程成本是比较高的,因为它涉及到要与操作系统进行交互。而使用线程池可以很好的提高性能,

        尤其是当程序中要创建大量生存期很短的线程时,更应该考虑使用线程池。

                线程池里的每一个线程代码结束后,并不会死亡,而是再次回到线程池中成为空闲状态,等待下一个对象来使用。

        在JDK5之前,我们必须手动实现自己的线程池,从JDK5开始,Java内置支持线程池。


        JDK5新增了一个Executors工厂类来产生线程池,有如下几个方法

                public static ExecutorService newCachedThreadPool()

                public static ExecutorService newFixedThreadPool(int nThreads)

                public static ExecutorService newSingleThreadExecutor()


 这些方法的返回值是ExecutorService对象,该对象表示一个线程池,可以执行Runnable对象或者Callable对象代表的

线程。

            它提供了如下方法

                    Future<?> submit(Runnable task)
                    <T> Future<T> submit(Callable<T> task)
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值