集合框架Collection的若干知识点--黑马程序员
2014-08-13 17:05
225 查看
在java中多线程之间的通信,本篇主要说明的是多线程之间的通信,共同操作一个资源,以及线程中出现的死锁现象,以及出现线程中重复生产的问题,通过同步线程可以解决这些问题,同步线程同一进程的多个线程共享同一片存储空间,在带来方便的同时,也带来了访问冲突这个严重的问题。Java语言提供了专门机制以解决这种冲突,有效避免了同一个数据对象被多个线程同时访问。
由于我们可以通过 private 关键字来保证数据对象只能被方法访问,所以我们只需针对方法提出一套机制,这套机制就是synchronized 关键字,它包括两种用法:synchronized 方法和 synchronized 块。
这下面的代码中都可以详细的体现出来,其代码如下:
public class ProducerCustumerDemo {
/**
* @param args
*/
public static void main(String[] args) {
//着这里传建一个资源类,是为了多线程之间保持操作的是一个资源,用构造函数等的方式传递到线程类中
Resouce resouce=new Resouce();
//创建多个生产和消费的线程类
Producer producer1=new Producer(resouce);
Producer producer2=new Producer(resouce);
Custumer custumer1=new Custumer(resouce);
Custumer custumer2=new Custumer(resouce);
new Thread(producer1).start();
new Thread(producer2).start();
new Thread(custumer1).start();
new Thread(custumer2).start();
}
//定义一个线程共享的一个资源类
static class Resouce{
//商品的ID
private int id;
//商品的名字
private String name;
//用于判断是否生产或者消费的数据,
private boolean flag=false;
//同步方法,是为了线程之间保持数据的一致性,不会出现意外的情况发生
public synchronized void set(String name)
{
//这里用while循环是为了防止多个线程,重复生产的情况
while(flag)
try {
this.wait();//线程等待,也即是放弃运行的资格
} catch (Exception e) {
// TODO: handle exception
}
this.name=name+id++;
//获取当前线程的名称
String currentThread=Thread.currentThread().getName();
System.out.println(currentThread+"生产"+this.name+"....");
//消费之后,让消费的线程继续消费该商品
this.flag=true;
this.notifyAll();
}
public synchronized void out()
{
//这里用while循环是为了防止多个线程,多消费情况
while(!flag)
try {
this.wait();//线程等待,也即是放弃运行的资格
} catch (Exception e) {
// TODO: handle exception
}
//获取当前线程的名称
String currentThread=Thread.currentThread().getName();
System.out.println(".........."+currentThread+"消费了"+this.name);
//消费之后,让生产的线程继续生产产品
this.flag=false;
//唤醒线程池中的线程,这里不用notiy()是因为这里可能出现死锁的现象
this.notifyAll();
}
}
//生产商品的线程类
static class Producer implements Runnable{
//顶一个资源类对象
Resouce resouce=null;
public Producer(Resouce re) {
this.resouce=re;
}
@Override
public void run() {
for(int i=0;i<100;i++)
resouce.set("小米电视");
}
}
//消费商品的线程类
static class Custumer implements Runnable{
Resouce resouce=null;
public Custumer(Resouce re) {
this.resouce=re;
}
public void run() {
for(int i=0;i<100;i++)
resouce.out();
}
}
}
由于我们可以通过 private 关键字来保证数据对象只能被方法访问,所以我们只需针对方法提出一套机制,这套机制就是synchronized 关键字,它包括两种用法:synchronized 方法和 synchronized 块。
这下面的代码中都可以详细的体现出来,其代码如下:
public class ProducerCustumerDemo {
/**
* @param args
*/
public static void main(String[] args) {
//着这里传建一个资源类,是为了多线程之间保持操作的是一个资源,用构造函数等的方式传递到线程类中
Resouce resouce=new Resouce();
//创建多个生产和消费的线程类
Producer producer1=new Producer(resouce);
Producer producer2=new Producer(resouce);
Custumer custumer1=new Custumer(resouce);
Custumer custumer2=new Custumer(resouce);
new Thread(producer1).start();
new Thread(producer2).start();
new Thread(custumer1).start();
new Thread(custumer2).start();
}
//定义一个线程共享的一个资源类
static class Resouce{
//商品的ID
private int id;
//商品的名字
private String name;
//用于判断是否生产或者消费的数据,
private boolean flag=false;
//同步方法,是为了线程之间保持数据的一致性,不会出现意外的情况发生
public synchronized void set(String name)
{
//这里用while循环是为了防止多个线程,重复生产的情况
while(flag)
try {
this.wait();//线程等待,也即是放弃运行的资格
} catch (Exception e) {
// TODO: handle exception
}
this.name=name+id++;
//获取当前线程的名称
String currentThread=Thread.currentThread().getName();
System.out.println(currentThread+"生产"+this.name+"....");
//消费之后,让消费的线程继续消费该商品
this.flag=true;
this.notifyAll();
}
public synchronized void out()
{
//这里用while循环是为了防止多个线程,多消费情况
while(!flag)
try {
this.wait();//线程等待,也即是放弃运行的资格
} catch (Exception e) {
// TODO: handle exception
}
//获取当前线程的名称
String currentThread=Thread.currentThread().getName();
System.out.println(".........."+currentThread+"消费了"+this.name);
//消费之后,让生产的线程继续生产产品
this.flag=false;
//唤醒线程池中的线程,这里不用notiy()是因为这里可能出现死锁的现象
this.notifyAll();
}
}
//生产商品的线程类
static class Producer implements Runnable{
//顶一个资源类对象
Resouce resouce=null;
public Producer(Resouce re) {
this.resouce=re;
}
@Override
public void run() {
for(int i=0;i<100;i++)
resouce.set("小米电视");
}
}
//消费商品的线程类
static class Custumer implements Runnable{
Resouce resouce=null;
public Custumer(Resouce re) {
this.resouce=re;
}
public void run() {
for(int i=0;i<100;i++)
resouce.out();
}
}
}
相关文章推荐
- 黑马程序员-集合框架Collection的若干知识点
- 黑马程序员:JAVA集合框架知识点一
- 黑马程序员_集合框架Collection
- 黑马程序员_Collection框架知识点
- 黑马程序员——java基础——集合框架(1)Collection
- 黑马程序员_Java基础_集合框架成员Collection
- 黑马程序员:JAVA集合框架知识点二
- 黑马程序员_java_集合框架_Collection_List_Set_Map_泛型
- 黑马程序员_学习笔记:9) 集合框架1:Collection(List、Set)、Iterator、List(ArrayList、LinkedList、Vector)
- 黑马程序员--Java面向对象——集合框架(Collection)
- 黑马程序员_Java第14天知识总结_集合类(集合框架)_Collection_迭代器_List_Set_HashSet
- 【黑马程序员】java中----------Collection集合框架
- 黑马程序员——java第十四、五、六天:集合框架(一:Collection、Map)
- 黑马程序员_java基础6-集合框架Collection和泛型
- 黑马程序员_java基础6-集合框架Collection和泛型
- 黑马程序员---集合框架(Collection)和泛型
- 黑马程序员——java基础之集合框架(Collection 和 Map)
- 黑马程序员-集合框架之Collection
- 黑马程序员------毕老师视频笔记第13-17天------集合框架(Collection)
- 关于集合框架Collection基础知识点的理解掌握