A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 梁航斌 中级黑马   /  2013-4-8 15:59  /  1770 人查看  /  6 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 梁航斌 于 2013-4-9 08:18 编辑

静态同步函数,同步函数为了保险起见都用obj锁可以吗?有什么好的建议,之前视频有看,但现在又忘得差不多了。

评分

参与人数 1技术分 +1 收起 理由
陈丽莉 + 1

查看全部评分

6 个回复

倒序浏览
不一定的,并发线程中与共享变量有关的程序段称为临界区。学习毕老师的视频后,我们知道java中用关键字synchronized声明一段临界区,只要该为临界区加的是同一把锁就可以实现同步的,这里是我写过的代码,读者和写者问题,经典的同步问题。请认真看下吧,希望能帮到你哦。
  1. /**
  2. * 题目:用多线程同步思想实现对某个共享缓冲区的读写操作的设计,即一旦写入数据,马上读走。
  3. * 线程同步,说白了,强调的是先后次序,也就是说必须等我这边忙完了,你那边才开始。
  4. * */
  5. public class ReaderAndWrite {

  6.         public static void main(String[] args) {
  7.                
  8.                 Buffer buffer = new Buffer();
  9.                 String[] datas = {"张三","李四","王五","赵六"};
  10.                 new writer(buffer,datas).start();
  11.                 new Reader(buffer,datas).start();
  12.         }
  13. }

  14. class Buffer{
  15.         private String data;
  16.         private boolean isNull = true;//读写线程通信的信号量,true表示缓冲区为空,可写
  17.         public  void putData(String data){
  18.                 while (!isNull) {//等待isNull为true,即等待数据被读走
  19.                         try {
  20.                                 this.wait();
  21.                         } catch (InterruptedException e) {
  22.                                 e.printStackTrace();
  23.                         }
  24.                 }
  25.                 this.data = data;//此时isNull为true,即前一个数据已被取走
  26.                 isNull = false;//将信号量设为false,表示缓冲区不为空,用以通知读进程
  27.                 notify();//唤醒等待的读线程,以进行读取刚刚存入的数据
  28.         }
  29.        
  30.         public  String getData(){
  31.                 while (isNull) {//此时若isNull为true,即无数据,则等待isNull为false,即等待写入数据
  32.                        
  33.                         try {
  34.                                 this.wait();
  35.                         } catch (InterruptedException e) {
  36.                                 e.printStackTrace();
  37.                         }
  38.                 }
  39.                 isNull = true;//将信号量设为true,表示缓冲区为空,用以通知写进程
  40.                 notify();//唤醒等待的写线程,以进行写操作
  41.                 return data;//有数据则返回当前数据
  42.         }
  43. }

  44. class writer extends Thread{
  45.         private Buffer buffer;
  46.         private String[] datas;
  47.         public writer(Buffer buffer,String[] datas) {
  48.                 this.buffer = buffer;
  49.                 this.datas = datas;
  50.         }
  51.         public  void run(){       
  52.                 //很明显,涉及到缓冲区,则可以将表示缓冲区的共享变量设为锁
  53.                 synchronized (buffer) {
  54.                         for(int i = 0;i<datas.length;i++){
  55.                                 buffer.putData(datas[i]);
  56.                                 System.out.println("写入:"+datas[i]);       
  57.                         }
  58.                 }
  59.         }
  60. }

  61. class Reader extends Thread{
  62.         private Buffer buffer;
  63.         private String[] datas;
  64.         public Reader(Buffer buffer,String[] datas) {
  65.                 this.buffer = buffer;
  66.                 this.datas = datas;
  67.         }
  68.         public void run(){
  69.                 //使用与写操作相同的缓冲区,则设置同一把锁
  70.                 synchronized (buffer) {
  71.                         for(int i = 0;i<datas.length;i++){
  72.                                 System.out.println("读取:"+buffer.getData());       
  73.                         }
  74.                 }
  75.         }
  76. }
复制代码

评分

参与人数 1技术分 +2 收起 理由
陈丽莉 + 2 25分咯~

查看全部评分

回复 使用道具 举报
若还有问题,继续追问; 没有的话,将帖子分类改成【已解决】哦~

点进自己的帖子,编辑->标题左侧有下拉菜单->改变分类->保存~

点评

嘿嘿,是哦,还需再接再厉的,谢斑竹啦!  发表于 2013-4-9 07:13
回复 使用道具 举报
一般锁有3个  obj  this  和类名.class
静态没有this指针  静态同步函数使用的锁就是他所在的类的   字节码文件对象
就是 类名.class  这就是静态同步函数使用的锁.
回复 使用道具 举报
建议使用lock对象
回复 使用道具 举报
函数要是想同步的话,必须保证引用的同一把锁,但是静态函数是先于构造函数加载的,所以使用本类对象不行,可以使用Object类的对象,因为Object类是唯一的,还可以用本类的字节码,因为一个类的字节码只有一份。
回复 使用道具 举报
whs_nk 发表于 2013-4-8 22:06
不一定的,并发线程中与共享变量有关的程序段称为临界区。学习毕老师的视频后,我们知道java中用关键字sync ...

非常感谢,很好的例子
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马