黑马程序员技术交流社区

标题: 多线程问题 [打印本页]

作者: 小白马__^o^    时间: 2014-8-8 15:54
标题: 多线程问题
本帖最后由 小白马__^o^ 于 2014-8-8 16:00 编辑

各位大神啊! 帮小弟看一下这道程序,执行不下去啊!
程序要求是这样的:
有四个线程1、2、3、4。线程1的功能就是输出1,线程2的功能就是输出2,以此类推.........现在有四个文件ABCD。初始都为空。现要让四个文件呈如下格式:
A:1 2 3 4 1 2....
B:2 3 4 1 2 3....
C:3 4 1 2 3 4....   
D:4 1 2 3 4 1....

这是小弟写的代码,可是就是有问题!还请大神们指导指导!

  1. import java.util.concurrent.ExecutorService;
  2. import java.util.concurrent.Executors;
  3. import java.util.concurrent.locks.Condition;        
  4. import java.util.concurrent.locks.*;

  5. public class Test06
  6. {
  7.         public static void main(String args[])
  8.         {
  9.                 ShiXian shi = new ShiXian();
  10.                
  11.                 ExecutorService service = Executors.newFixedThreadPool(4);        //实例化一个线程池,池里面可以放4个线程
  12.                 service.execute(new Thread(new Thread01(shi)));                //将线程1放进去池中进行执行
  13.                 service.execute(new Thread(new Thread02(shi)));
  14.                 service.execute(new Thread(new Thread03(shi)));
  15.                 service.execute(new Thread(new Thread04(shi)));
  16.         }
  17. }
  18. class ShiXian
  19. {
  20.         Lock lock = new ReentrantLock();
  21.         Condition ThreadA = lock.newCondition();         
  22.         Condition ThreadB = lock.newCondition();         
  23.         Condition ThreadC = lock.newCondition();         
  24.         Condition ThreadD = lock.newCondition();        
  25.         int flag = 1;
  26.         //int [] buff = new int[6];

  27.         public void lock01()     //加锁方法1
  28.         {
  29.                 for (int i=1; i <=6;)
  30.                  {
  31.                         lock.lock();
  32.                         try
  33.                         {
  34.                                 while(flag != 1)
  35.                                 {
  36.                                         try
  37.                                         {
  38.                                                 ThreadA.await();
  39.                                         }
  40.                                         catch (Exception e)
  41.                                         {
  42.                                                 e.printStackTrace();
  43.                                         }
  44.                                 }
  45.                                 System.out.print(1 + " ");
  46.                                 //buff[0] = flag;
  47.                                 flag = 2;
  48.                                 ThreadB.signal();
  49.                                  i++ ;
  50.                         }
  51.                         finally
  52.                         {
  53.                                 lock.unlock();
  54.                         }
  55.                 }
  56.         }
  57.         public void lock02()    //加锁方法2
  58.         {
  59.                 for (int i=1; i <=6; i++ )
  60.                  {
  61.                         lock.lock();
  62.                         try
  63.                         {
  64.                                 while(flag != 2)
  65.                                 {
  66.                                         try
  67.                                         {
  68.                                                 ThreadA.await();
  69.                                         }
  70.                                         catch (Exception e)
  71.                                         {
  72.                                                 e.printStackTrace();
  73.                                         }
  74.                                 }
  75.                                 System.out.print(2 + " ");
  76.                                 //System.out.println();
  77.                                 //buff[1] = flag;
  78.                                 flag = 3;
  79.                                 ThreadC.signal();
  80.                                  i++ ;
  81.                         }
  82.                         finally
  83.                         {
  84.                                 lock.unlock();
  85.                         }
  86.                 }
  87.         }
  88.         public void lock03()    //加锁方法3
  89.         {
  90.                 for (int i=1; i <=6; i++ )
  91.                  {
  92.                         lock.lock();
  93.                         try
  94.                         {
  95.                                 while(flag != 3)
  96.                                 {
  97.                                         try
  98.                                         {
  99.                                                 ThreadA.await();
  100.                                         }
  101.                                         catch (Exception e)
  102.                                         {
  103.                                                 e.printStackTrace();
  104.                                         }
  105.                                 }
  106.                                 System.out.print(3 + " ");
  107.                                 //buff[2] = flag;
  108.                                 flag = 4;
  109.                                 ThreadD.signal();
  110.                                  i++ ;
  111.                         }
  112.                         finally
  113.                         {
  114.                                 lock.unlock();
  115.                         }
  116.                 }
  117.         }
  118.         public void lock04()    //加锁方法4
  119.         {
  120.                 for (int i=1; i <=6; i++ )
  121.                  {
  122.                         lock.lock();
  123.                         try
  124.                         {
  125.                                 while(flag != 4)
  126.                                 {
  127.                                         try
  128.                                         {
  129.                                                 ThreadA.await();
  130.                                         }
  131.                                         catch (Exception e)
  132.                                         {
  133.                                                 e.printStackTrace();
  134.                                         }
  135.                                 }
  136.                                 System.out.print(4 + " ");
  137.                                 //buff[3] = flag;

  138.                                 flag = 1;
  139.                                 ThreadA.signal();
  140.                                  i++ ;
  141.                         }
  142.                         finally
  143.                         {
  144.                                 lock.unlock();
  145.                         }
  146.                 }
  147.         }
  148. }

  149. class Thread01 implements Runnable   //线程1
  150. {
  151.         ShiXian shi = null;

  152.         public Thread01(ShiXian shi)
  153.         {
  154.                 this.shi = shi;
  155.         }
  156.         public void run()
  157.         {
  158.                 shi.lock01();
  159.         }
  160. }

  161. class Thread02 implements Runnable   //线程2
  162. {
  163.         ShiXian shi = null;

  164.         public Thread02(ShiXian shi)
  165.         {
  166.                 this.shi = shi;
  167.         }
  168.         public void run()
  169.         {
  170.                 shi.lock02();
  171.         }
  172. }

  173. class Thread03 implements Runnable   //线程3
  174. {
  175.         ShiXian shi = null;

  176.         public Thread03(ShiXian shi)
  177.         {
  178.                 this.shi = shi;
  179.         }
  180.         public void run()
  181.         {
  182.                 shi.lock03();
  183.         }
  184. }

  185. class Thread04 implements Runnable  //线程4
  186. {
  187.         ShiXian shi = null;

  188.         public Thread04(ShiXian shi)
  189.         {
  190.                 this.shi = shi;
  191.         }
  192.         public void run()
  193.         {
  194.                 shi.lock04();
  195.         }
  196. }

复制代码




然后程序停在哪儿就不往下执行了,这是怎么回事儿啊!






作者: 天黑偷牛    时间: 2014-8-8 16:47
额(⊙o⊙)…,我水平有点低,还没看懂
作者: 天黑偷牛    时间: 2014-8-8 16:48
应该是死锁吧,我还没找到在哪
作者: 小白马__^o^    时间: 2014-8-8 18:56
天黑偷牛 发表于 2014-8-8 16:48
应该是死锁吧,我还没找到在哪

恩恩! 我想应该也是死锁吧! 但是就不知道怎么解决! 哎!郁闷啊!还请大神指教!{:2_32:}
作者: 回头浪子心    时间: 2014-8-8 20:20
呵呵,,, 我不会告诉你,我也不懂~~~
作者: 乐此不疲    时间: 2014-8-8 20:59
你的await跟sigal用的挺混乱的,应该交替A-B B-C C-D D-A这样保证循环,还有你的for循环中i++有时出现在for之后,有的出现在语句体中。。。  帮你改了下
  1. import java.util.concurrent.ExecutorService;
  2. import java.util.concurrent.Executors;
  3. import java.util.concurrent.locks.Condition;        
  4. import java.util.concurrent.locks.*;

  5. public class Test06
  6. {
  7.         public static void main(String args[])
  8.         {
  9.                 ShiXian shi = new ShiXian();
  10.                
  11.                 ExecutorService service = Executors.newFixedThreadPool(4);        //实例化一个线程池,池里面可以放4个线程
  12.                 service.execute(new Thread(new Thread01(shi)));                //将线程1放进去池中进行执行
  13.                 service.execute(new Thread(new Thread02(shi)));
  14.                 service.execute(new Thread(new Thread03(shi)));
  15.                 service.execute(new Thread(new Thread04(shi)));
  16.         }
  17. }
  18. class ShiXian
  19. {
  20.         Lock lock = new ReentrantLock();
  21.         Condition ThreadA = lock.newCondition();         
  22.         Condition ThreadB = lock.newCondition();         
  23.         Condition ThreadC = lock.newCondition();         
  24.         Condition ThreadD = lock.newCondition();        
  25.         int flag = 1;
  26.         //int [] buff = new int[6];

  27.         public void lock01()     //加锁方法1
  28.         {
  29.                 for (int i=1; i <=6;)
  30.                  {
  31.                         lock.lock();
  32.                         try
  33.                         {
  34.                                 while(flag != 1)
  35.                                 {
  36.                                         try
  37.                                         {
  38.                                                 ThreadA.await();
  39.                                         }
  40.                                         catch (Exception e)
  41.                                         {
  42.                                                 e.printStackTrace();
  43.                                         }
  44.                                 }
  45.                                 System.out.print(1 + " ");
  46.                                 //buff[0] = flag;
  47.                                 flag = 2;
  48.                                 ThreadB.signal();
  49.                                  i++ ;
  50.                         }
  51.                         finally
  52.                         {
  53.                                 lock.unlock();
  54.                         }
  55.                 }
  56.         }
  57.         public void lock02()    //加锁方法2
  58.         {
  59.                 for (int i=1; i <=6; i++ )
  60.                  {
  61.                         lock.lock();
  62.                         try
  63.                         {
  64.                                 while(flag != 2)
  65.                                 {
  66.                                         try
  67.                                         {
  68.                                                 ThreadA.await();
  69.                                         }
  70.                                         catch (Exception e)
  71.                                         {
  72.                                                 e.printStackTrace();
  73.                                         }
  74.                                 }
  75.                                 System.out.print(2 + " ");
  76.                                 //System.out.println();
  77.                                 //buff[1] = flag;
  78.                                 flag = 3;
  79.                                 ThreadC.signal();
  80.                                  i++ ;
  81.                         }
  82.                         finally
  83.                         {
  84.                                 lock.unlock();
  85.                         }
  86.                 }
  87.         }
  88.         public void lock03()    //加锁方法3
  89.         {
  90.                 for (int i=1; i <=6; i++ )
  91.                  {
  92.                         lock.lock();
  93.                         try
  94.                         {
  95.                                 while(flag != 3)
  96.                                 {
  97.                                         try
  98.                                         {
  99.                                                 ThreadA.await();
  100.                                         }
  101.                                         catch (Exception e)
  102.                                         {
  103.                                                 e.printStackTrace();
  104.                                         }
  105.                                 }
  106.                                 System.out.print(3 + " ");
  107.                                 //buff[2] = flag;
  108.                                 flag = 4;
  109.                                 ThreadD.signal();
  110.                                  i++ ;
  111.                         }
  112.                         finally
  113.                         {
  114.                                 lock.unlock();
  115.                         }
  116.                 }
  117.         }
  118.         public void lock04()    //加锁方法4
  119.         {
  120.                 for (int i=1; i <=6; i++ )
  121.                  {
  122.                         lock.lock();
  123.                         try
  124.                         {
  125.                                 while(flag != 4)
  126.                                 {
  127.                                         try
  128.                                         {
  129.                                                 ThreadA.await();
  130.                                         }
  131.                                         catch (Exception e)
  132.                                         {
  133.                                                 e.printStackTrace();
  134.                                         }
  135.                                 }
  136.                                 System.out.print(4 + " ");
  137.                                 //buff[3] = flag;

  138.                                 flag = 1;
  139.                                 ThreadA.signal();
  140.                                  i++ ;
  141.                         }
  142.                         finally
  143.                         {
  144.                                 lock.unlock();
  145.                         }
  146.                 }
  147.         }
  148. }

  149. class Thread01 implements Runnable   //线程1
  150. {
  151.         ShiXian shi = null;

  152.         public Thread01(ShiXian shi)
  153.         {
  154.                 this.shi = shi;
  155.         }
  156.         public void run()
  157.         {
  158.                 shi.lock01();
  159.         }
  160. }

  161. class Thread02 implements Runnable   //线程2
  162. {
  163.         ShiXian shi = null;

  164.         public Thread02(ShiXian shi)
  165.         {
  166.                 this.shi = shi;
  167.         }
  168.         public void run()
  169.         {
  170.                 shi.lock02();
  171.         }
  172. }

  173. class Thread03 implements Runnable   //线程3
  174. {
  175.         ShiXian shi = null;

  176.         public Thread03(ShiXian shi)
  177.         {
  178.                 this.shi = shi;
  179.         }
  180.         public void run()
  181.         {
  182.                 shi.lock03();
  183.         }
  184. }

  185. class Thread04 implements Runnable  //线程4
  186. {
  187.         ShiXian shi = null;

  188.         public Thread04(ShiXian shi)
  189.         {
  190.                 this.shi = shi;
  191.         }
  192.         public void run()
  193.         {
  194.                 shi.lock04();
  195.         }
  196. }
复制代码

作者: fantacyleo    时间: 2014-8-8 21:03
那么多锁,唯恐不死锁的节奏啊。。。其实用CyclicBarrier就很容易解决了。
  1. import java.util.concurrent.*;
  2. import java.io.*;

  3. /** 有四个线程1、2、3、4。线程1的功能就是输出1,线程2的功能就是输出2,以此类推....现在有四个文件ABCD。初始都为空。现要让四个文件呈如下格式:
  4. * A:1 2 3 4 1 2....
  5. * B:2 3 4 1 2 3....
  6. * C:3 4 1 2 3 4....   
  7. * D:4 1 2 3 4 1....
  8. *
  9. * 思路:
  10. *         四个线程分别写四个文件,写好之后,在同一个CyclicBarrier上等待,执行barrier action,互换各自要写入的文件,再开始下一轮写入
  11. */

  12. public class MultipleThreadWriter {
  13.        
  14.         public static void main(String[] args) throws Exception {

  15.                 FileWriter file1 = new FileWriter("c:\\1.txt");
  16.                 FileWriter file2 = new FileWriter("c:\\2.txt");
  17.                 FileWriter file3 = new FileWriter("c:\\3.txt");
  18.                 FileWriter file4 = new FileWriter("c:\\4.txt");

  19.                 final ThreadWriter tw1 = new ThreadWriter(file1, '1');
  20.                 final ThreadWriter tw2 = new ThreadWriter(file2, '2');
  21.                 final ThreadWriter tw3 = new ThreadWriter(file3, '3');
  22.                 final ThreadWriter tw4 = new ThreadWriter(file4, '4');

  23.                 CyclicBarrier barrier = new CyclicBarrier(4, new Runnable() {
  24.                         public void run() {
  25.                                 FileWriter temp1 = tw1.getFileWriter();
  26.                                 FileWriter temp2 = tw2.getFileWriter();
  27.                                 FileWriter temp3 = tw3.getFileWriter();
  28.                                 FileWriter temp4 = tw4.getFileWriter();

  29.                                 // 互换四个线程的写入文件
  30.                                 tw1.setFileWriter(temp4);
  31.                                 tw2.setFileWriter(temp1);
  32.                                 tw3.setFileWriter(temp2);
  33.                                 tw4.setFileWriter(temp3);
  34.                         }
  35.                 });
  36.                
  37.                 tw1.setBarrier(barrier);
  38.                 tw2.setBarrier(barrier);
  39.                 tw3.setBarrier(barrier);
  40.                 tw4.setBarrier(barrier);
  41.                
  42.                 ExecutorService exec = Executors.newCachedThreadPool();
  43.                 exec.execute(tw1);
  44.                 exec.execute(tw2);
  45.                 exec.execute(tw3);
  46.                 exec.execute(tw4);

  47.                 TimeUnit.MILLISECONDS.sleep(10);
  48.                 exec.shutdownNow();
  49.         }


  50. }


  51. class ThreadWriter implements Runnable {
  52.         private FileWriter fw;
  53.         private char c;
  54.         private CyclicBarrier barrier;
  55.         public ThreadWriter(FileWriter fw, char c) {
  56.                 this.fw = fw;
  57.                 this.c = c;
  58.         }

  59.         public void setFileWriter(FileWriter fw) {
  60.                 this.fw = fw;
  61.         }

  62.         public FileWriter getFileWriter() {
  63.                 return fw;
  64.         }
  65.        
  66.         public void setBarrier(CyclicBarrier barrier) {
  67.                 this.barrier = barrier;
  68.         }

  69.         public void run() {
  70.                 try {
  71.                         while (!Thread.interrupted()) {
  72.                                 fw.write(c + " ");
  73.                                 barrier.await();
  74.                         }
  75.                 } catch(InterruptedException e) {
  76.                        
  77.                 } catch(BrokenBarrierException e) {
  78.                        
  79.                 } catch(IOException e) {
  80.                        
  81.                 } finally {
  82.                         try {
  83.                                 fw.close();
  84.                         } catch (IOException e) {
  85.                                
  86.                         }
  87.                 }
  88.                
  89.         }
  90. }
复制代码

作者: lcycr    时间: 2014-8-8 21:05
二楼的代码太给力了
作者: 小白马__^o^    时间: 2014-8-8 22:02
fantacyleo 发表于 2014-8-8 21:03
那么多锁,唯恐不死锁的节奏啊。。。其实用CyclicBarrier就很容易解决了。

fantacyleo  大神啊! 你真的太给力了! 厉害!小弟受教了!{:2_32:}
作者: 刘小记.    时间: 2014-8-8 22:13
学习学习




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2