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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 静以修身 中级黑马   /  2013-9-24 20:57  /  2231 人查看  /  5 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 静以修身 于 2013-9-24 21:00 编辑

问题在代码注释中的

package threadtest;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

public class BlockingQueueTest {
        public static void main(String[] args) {
                final BlockingQueue queue = new ArrayBlockingQueue(3);
                for(int i=0;i<2;i++){
                        new Thread(){
                                public void run(){
                                        while(true){
                                                try {
                                                        Thread.sleep((long)(Math.random()*1000));
                                                        System.out.println(Thread.currentThread().getName() + "准备放数据!");                                                        
                                                        queue.put(1);   //我的问题是:怎么让这行代码和下一行代码一起执行
                                                        System.out.println(Thread.currentThread().getName() + "已经放了数据," +                                                         
                                                                                "队列目前有" + queue.size() + "个数据");
                                                } catch (InterruptedException e) {
                                                        e.printStackTrace();
                                                }

                                        }
                                }
                                
                        }.start();
                }
               
                new Thread(){
                        public void run(){
                                while(true){
                                        try {
                                                //将此处的睡眠时间分别改为100和1000,观察运行结果
                                                Thread.sleep(1000);
                                                System.out.println(Thread.currentThread().getName() + "准备取数据!");
                                                queue.take();  //问题:怎么让这行代码和下一行代码一起执行
                                                System.out.println(Thread.currentThread().getName() + "已经取走数据," +                                                         
                                                                "队列目前有" + queue.size() + "个数据");                                       
                                        } catch (InterruptedException e) {
                                                e.printStackTrace();
                                        }
                                }
                        }
                        
                }.start();                        
        }
}

结果如下:
Thread-0已经放了数据,队列目前有3个数据         //这行和下一行代码之所以打印出3个数据就是因为注释中的两行代码没有一起执行
Thread-2已经取走数据,队列目前有3个数据         //怎样才能让它们一起执行啊,让它们同步,加上synchronized(BlockingQueueTest)不行啊



评分

参与人数 1技术分 +1 收起 理由
乔兵 + 1

查看全部评分

5 个回复

倒序浏览
  1. import java.util.concurrent.ArrayBlockingQueue;
  2. import java.util.concurrent.BlockingQueue;
  3. public class BlockingQueueTest {
  4.         public static void main(String[] args){
  5.                 final BlockingQueue queue = new ArrayBlockingQueue(3);

  6.                 for(int i=0;i<2;i++){
  7.                         new Thread(){
  8.                                 public void run(){
  9.                                         while(true){
  10.                                                 try{
  11.                                                         Thread.sleep((long)(Math.random()*1000));
  12.                                                         System.out.println(Thread.currentThread().getName() + "准备放数据");
  13.                                                         queue.put(1);//我的问题是:怎么让这行代码和下一行代码一起执行
  14.                                                         System.out.println(Thread.currentThread().getName()+"已放数据,"
  15.                                                         +"目前队列有"+queue.size()+"个数据");
  16.                                                 }catch(InterruptedException e){
  17.                                                         e.printStackTrace();
  18.                                                 }
  19.                                         }
  20.                                 }
  21.                         }.start();
  22.                 }
  23.                 new Thread(){
  24.                         public void run(){
  25.                                 while(true){
  26.                                         try{//将此处的睡眠时间分别改为100和1000,观察运行结果
  27.                                                 Thread.sleep(1000);
  28.                                                 System.out.println(Thread.currentThread().getName()+"准备取出数据,");
  29.                                                 queue.take();//问题:怎么放这行代码和下一行代码一起执行。
  30.                                                 System.out.println(Thread.currentThread().getName()+"已经取走数据,"+
  31.                                                         "队列目前有"+queue.size()+"个数据");
  32.                                         } catch(InterruptedException e){
  33.                                                 e.printStackTrace();
  34.                                         }
  35.                                 }
  36.                         }
  37.                 }.start();
  38.         }
  39. }
  40. /*
  41. Thread-0已经放了数据,队列目前有3个数据                //这行和下一行diamond之所以打印出了饿个数据就是因为注释中的两行代码没有一起执行
  42. Thread-2已经取走数据,队列目前有3个数据                //怎么才能让他们一起执行啊,让他们同步,加上synchronized(BlockingQueueTest)不行啊
  43. */
复制代码
你的代码应该放在代码区这样方便复制,我帮你弄了,希望有同学能帮你解决吧。
回复 使用道具 举报
  加锁可以解决
回复 使用道具 举报
楼主看一下,加一个锁。
  1. package cn.itcast.day1;
  2. import java.util.concurrent.ArrayBlockingQueue;
  3. import java.util.concurrent.BlockingQueue;
  4. public class BlockingQueueTest {
  5.         public static void main(String[] args){
  6.                 final BlockingQueue queue = new ArrayBlockingQueue(3);

  7.                 for(int i=0;i<2;i++){
  8.                         new Thread(){
  9.                                 public void run(){
  10.                                         while(true){
  11.                                                 try{
  12.                                                         Thread.sleep((long)(Math.random()*1000));
  13.                                                         System.out.println(Thread.currentThread().getName() + "准备放数据");
  14.                                                         queue.put(1);//我的问题是:怎么让这行代码和下一行代码一起执行
  15.                                                         System.out.println(Thread.currentThread().getName()+"已放数据,"
  16.                                                         +"目前队列有"+queue.size()+"个数据");
  17.                                                 }catch(InterruptedException e){
  18.                                                         e.printStackTrace();
  19.                                                 }
  20.                                         }
  21.                                 }
  22.                         }.start();
  23.                 }
  24.                 new Thread(){
  25.                         public void run(){
  26.                                 while(true){
  27.                                         try{//将此处的睡眠时间分别改为100和1000,观察运行结果
  28.                                                 Thread.sleep(1000);
  29.                                                 System.out.println(Thread.currentThread().getName()+"准备取出数据,");
  30.                                                 
  31.                                                 synchronized (BlockingQueueTest.class) {
  32.                                                                                                         queue.take();//问题:怎么放这行代码和下一行代码一起执行。
  33.                                                                                                         System.out.println(Thread.currentThread().getName()+"已经取走数据,"+
  34.                                                         "队列目前有"+queue.size()+"个数据");
  35.                                                                                                 }
  36.                                                 
  37.                                         } catch(InterruptedException e){
  38.                                                 e.printStackTrace();
  39.                                         }
  40.                                 }
  41.                         }
  42.                 }.start();
  43.         }
  44. }
  45. /*
  46. Thread-0已经放了数据,队列目前有3个数据                //这行和下一行diamond之所以打印出了饿个数据就是因为注释中的两行代码没有一起执行
  47. Thread-2已经取走数据,队列目前有3个数据                //怎么才能让他们一起执行啊,让他们同步,加上synchronized(BlockingQueueTest)不行啊
  48. */
复制代码
回复 使用道具 举报
你可以给那两句话上加上
  1. synchronized(BlockingQueueTest.class)
  2. {
  3.      那两句代码的位置
  4. }
复制代码
记得两个线程都要加,一样的
我加了测试时候,是能满足你的要求的,但是会执行一段时间后会停着,不知道是否是其他代码的原因,里面有些代码我还不认识 {:soso_e113:}
回复 使用道具 举报
freehiker 发表于 2013-9-25 00:23
你可以给那两句话上加上记得两个线程都要加,一样的
我加了测试时候,是能满足你的要求的,但是会执行一段 ...

加了锁我也测试过,有行的也有不行的。前面打印出的那部分正常了,没有问题,但后面打印的又出现了原来的问题。还有如果两个线程都加的话会出现死锁的情况。比如当队列里已经有三个数据的时候,添加数据的线程抢到锁,这时因为队列已满不能添加会阻塞在线程里面,而又没有释放锁,导致获取数据的线程不能获取数据,因为添加数据的线程霸占了锁,这样会导致死锁啊。{:soso_e101:}
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马