黑马程序员技术交流社区

标题: 多线程代码、求解 [打印本页]

作者: Emperors    时间: 2014-4-15 20:48
标题: 多线程代码、求解
本帖最后由 Emperors 于 2014-4-16 23:26 编辑

  题目:
          多个线程同时出票,保证每张出票的编号连续且不重复。
   public class Demo{
public static void main(String args [])
{
SellTicket st1=new SellTicket();
st1.setName("线程1");
SellTicket st2=new SellTicket();
st2.setName("线程2");
SellTicket st3=new SellTicket();
st3.setName("线程3");
st1.start();
st2.start();
st3.start();
}
}


public class SellTicket extends Thread
{


private static int sd=0;
public void run()
{
for(int i=0;i<20;i++)
{
sell();
}
}
public synchronized void sell()
{
sd++;
System.out.println(currentThread().getName()+"买票"+"sd"+sd);
}
}




   编译可以通过,运行结果如下:线程1买票sd2
线程2买票sd2
线程1买票sd3
线程2买票sd4
线程1买票sd5
线程2买票sd7
线程1买票sd8
线程3买票sd8
线程2买票sd9
线程1买票sd10
线程3买票sd11
线程2买票sd12
线程1买票sd13
线程3买票sd14
线程2买票sd15
线程1买票sd16
线程3买票sd17
线程2买票sd18
线程1买票sd19
线程3买票sd20
线程2买票sd21
线程1买票sd22
线程3买票sd23
线程2买票sd24
线程1买票sd25
线程3买票sd26
线程2买票sd27
线程1买票sd28
线程3买票sd29
线程2买票sd30
线程1买票sd31
线程3买票sd32
线程2买票sd33
线程1买票sd34
线程3买票sd35
线程2买票sd36
线程1买票sd37
线程3买票sd38
线程2买票sd39
线程1买票sd40
线程3买票sd41
线程2买票sd42
线程1买票sd43
线程3买票sd44
线程2买票sd45
线程1买票sd46
线程3买票sd47
线程2买票sd48
线程1买票sd49
线程3买票sd50
线程2买票sd51
线程1买票sd52
线程3买票sd53
线程2买票sd54
线程1买票sd55
线程3买票sd56
线程2买票sd57
线程3买票sd58
线程3买票sd59
线程3买票sd60
我认为原因是synchronized 没有锁住sell()方法,但是不知道为什么呢
请大神解析,谢谢!

synchronized 修饰sell() 就不会出现呢线程1买票sd2
线程2买票sd2







作者: 呆呆沙师妹    时间: 2014-4-15 21:07
我觉得你同步锁放错了地方,应该放在run()方法上。
  1. public class A{
  2.          public static void main(String args []){
  3.                  SellTicket st1=new SellTicket();
  4.                  st1.setName("线程1");
  5.                  SellTicket st2=new SellTicket();
  6.                  st2.setName("线程2");
  7.                  SellTicket st3=new SellTicket();
  8.                  st3.setName("线程3");
  9.                  st1.start();
  10.                  st2.start();
  11.                  st3.start();
  12.         }
  13. }
  14.      
  15. class SellTicket extends Thread{
  16.         private static int sd=0;
  17.         public synchronized void run(){
  18.                 for(int i=0;i<20;i++){
  19.                         sell();
  20.                 }
  21.         }
  22.        
  23.         public void sell(){
  24.                                 //这里可以合成一个语句
  25.                 System.out.println(currentThread().getName()+"买票"+"sd"+(++sd));
  26.         }
  27. }
复制代码

作者: optimisticpig    时间: 2014-4-15 21:11
  1. public class Demo
  2. {
  3.         public static void main(String args [])
  4.         {
  5.                 SellTicket st1=new SellTicket();
  6.                 st1.setName("线程1");
  7.                 SellTicket st2=new SellTicket();
  8.                 st2.setName("线程2");
  9.                 SellTicket st3=new SellTicket();
  10.                 st3.setName("线程3");
  11.                 st1.start();
  12.                 st2.start();
  13.                 st3.start();
  14.         }
  15. }


  16. class SellTicket extends Thread
  17. {
  18.         private static int sd=0;
  19.         public void run()
  20.         {
  21.                 for(int i=0;i<20;i++)
  22.                 {
  23.                         sell();
  24.                 }
  25.         }
  26.         public void sell()
  27.         {
  28.                 synchronized(Demo.class)
  29.                 {
  30.                 sd++;
  31.                 System.out.println(currentThread().getName()+"买票"+"sd"+sd);
  32.                 }
  33.         }
  34. }
复制代码


同步函数使用的锁是this。
楼主建立了3个线程,分别调用run方法,但是不是同一个锁,所以才会出现错票。改成同步代码块并声明锁后就没问题了。
作者: 月光海    时间: 2014-4-15 21:16
同步函数的锁是this,你上面创建了3个对象,对应的是3个不同的this,所以是不会锁住的,而且最好不要继承Thread,而是实现Runnable接口,万一你这个类以后还要继承其他的额类呢?
  1. public class Demo555{
  2.                 public static void main(String args [])
  3.                 {
  4.                         SellTicket s=new SellTicket();
  5.                         Thread st1=new Thread(s);
  6.                         Thread st2=new Thread(s);
  7.                         Thread st3=new Thread(s);
  8.                         st1.setName("线程1");
  9.                         st2.setName("线程2");
  10.                         st3.setName("线程3");
  11.                         st1.start();
  12.                         st2.start();
  13.                         st3.start();
  14.                 }
  15. }
  16. class SellTicket implements Runnable
  17. {


  18.         private static int sd=0;
  19.         public void run()
  20.         {
  21.                 for(int i=0;i<20;i++)
  22.                 {
  23.                         sell();
  24.                 }
  25.         }
  26.         public synchronized void sell()
  27.         {
  28.                 sd++;
  29.                 System.out.println(Thread.currentThread().getName()+"买票"+"sd"+sd);
  30.         }
  31. }
复制代码





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