关于线程的问题 synchronized 无论放哪里,只有一个Locket会执行动作,其它等待,实际上不会执行 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 http://bbs.csdn.net/topics/390645360 和这个贴是同一个人吗? 那你看看那贴的回复 你的问题归根结底还是没达到同步的效果。1.第一个问题,为什么到104呢?因为线程睡眠在外面,都是while运算基本上不可能有sleep的执行后的效果,所以在外面的话写不写都是一个样,出现104就是因为进程之间的值可以随时改变,static值可以有任何线程来更改,所以会出现104,而且你会发现同一张票会出现好几次。2.为啥会小于100呢,其实sleep写在里面,无形中给各个线程相互执行增加了容错机制,不至于各个线程一直再竞争,从而近乎合理的运算,其他也有一两个相同的票出现,也会出现100,101等数字,但近乎合理,如果把时间放大就更接近了3换成if之后每个线程就执行了一次,毋庸置疑的,不会多余五次的,正确的理解应该是每个线程共享一个变量ticketnum ,使他不至于小于0而且各个线程执行后的效果还得正确,楼主的代码没有考虑到同步只是正对同一个对象,而你已经在堆里生成了5个new对象了。如果不是同一个对象那就要同步一个共有的栈里的东西,如调用类里的static变量或是类,当然不建议用类作为同步对象,在真实的系统中如果将类“锁”住,可能会导致其他业务访问这个类。楼主修改代码修改如下,public class TimerContent { static String ss=""; public static void main(String args[]) throws Exception{ Tc t1=new Tc(1); Tc t2=new Tc(2); Tc t3=new Tc(3); Tc t4=new Tc(4); Tc t5=new Tc(5); Thread th1=new Thread(t1); Thread th2=new Thread(t2); Thread th3=new Thread(t3); Thread th4=new Thread(t4); Thread th5=new Thread(t5); th1.start(); th2.start(); th3.start(); th4.start(); th5.start(); } }class Tc implements java.lang.Runnable{ static int pp=100; static int count=0; private int aa; public Tc(int aa){ this.aa=aa; } public void run(){ while(pp>0){ synchronized(TimerContent.ss){ if(pp>0){ count++; System.out.println("第"+aa+"个窗口,第"+count+"张票"+", "+pp); pp--; } } try{ Thread.sleep(1); }catch(Exception e){ e.printStackTrace(); } } }},当然上面也可以不用同步,将TimerContent.ss也可以改为自定的变量,执行前执行后的值变化一下 可是我的静态变量设成100啊,每次在while循环的时候不是都会减小一次么?到0就不能再进行循环了,那不就是总共100次么?相当于100 张票。还有楼主的代码没有考虑到同步只是正对同一个对象,而你已经在堆里生成了5个new对象了。你说的这句,我不理解啊,我要模拟5个售票窗口那new5个窗口对象不对吗?那应该怎么理解呢?题就是要模拟5个售票窗口售出100张票,并且打印票的号 再补一句啊,如果把sleep放的里面再把sleep的时间调长了,那我做的算符合题意吗?感觉线程好难理解啊,麻烦你啦 直接回复你所有的问题,五个new对象,所以你原来的synchronized不起任何作用,原来的synchronized范围只是你的单个的new出来的对象,五个线程可以任意竞争,无顺序可言,所以要找一个对象或对象静态成员属性作为锁。至于你说的为什么“到0就不能再进行循环了,那不就是总共100次么?”,有没有考虑到每个类对象都是有事务的概念,不是只是允许一个对象来调,n个对象都可以调用这个方法,没有时间可言,没有顺序可言,所以完全有可能多个对象同时执行run方法,同时修改ticketnum 的值,比如说道100的时候完全可以四五个线程同事执行这个方法,当执行到--的时候大家都--,这就是出现了几个重复的票号,也有可能同时到100了,第一个先--了,后面的挨个--,就会出现大于100的情况。你的问题“你写的那个锁我也不明白锁到底应该加在什么地方啊?”根据你上面的代码,锁加载run方法上肯定不行的,因为这个run方法是实现的方法,无法更改其方法参数,必须在方法内部加锁已达到锁的目的,当然其他非线程业务加到方法是可以的,根据业务实现来确定锁加在哪。最后一个问题,“sleep时间加长”完全可以,不过线程参与量会变少,不是五个,随着时间加长,最后有可能只有一个线程参与,如果是现实中的买票,建议时间不要太长,意思一下就行了,才能观察到线程竞争的效果 分布式互斥算法问题 判断并等待所有线程终止 java内存溢出 改怎么改 打开有applet小程序的页面出现内存不能为read public static final 和 private static final 在执行效率上有啥区别? 一道常见面试题的答案 这是什么问题!! jcreater环境配置 我想在java程序中加一个定时器 哪位高手知道怎么配置ldap? Runtime.exec();命令行调用连续问题?? 帮忙检查一下这个程序错在哪 ?
1.第一个问题,为什么到104呢?因为线程睡眠在外面,都是while运算基本上不可能有sleep的执行后的效果,所以在外面的话写不写都是一个样,出现104就是因为进程之间的值可以随时改变,static值可以有任何线程来更改,所以会出现104,而且你会发现同一张票会出现好几次。
2.为啥会小于100呢,其实sleep写在里面,无形中给各个线程相互执行增加了容错机制,不至于各个线程一直再竞争,从而近乎合理的运算,其他也有一两个相同的票出现,也会出现100,101等数字,但近乎合理,如果把时间放大就更接近了
3换成if之后每个线程就执行了一次,毋庸置疑的,不会多余五次的,正确的理解应该是每个线程共享一个变量ticketnum ,使他不至于小于0而且各个线程执行后的效果还得正确,楼主的代码没有考虑到同步只是正对同一个对象,而你已经在堆里生成了5个new对象了。如果不是同一个对象那就要同步一个共有的栈里的东西,如调用类里的static变量或是类,当然不建议用类作为同步对象,在真实的系统中如果将类“锁”住,可能会导致其他业务访问这个类。楼主修改代码修改如下,
public class TimerContent { static String ss="";
public static void main(String args[]) throws Exception{
Tc t1=new Tc(1);
Tc t2=new Tc(2);
Tc t3=new Tc(3);
Tc t4=new Tc(4);
Tc t5=new Tc(5);
Thread th1=new Thread(t1);
Thread th2=new Thread(t2);
Thread th3=new Thread(t3);
Thread th4=new Thread(t4);
Thread th5=new Thread(t5);
th1.start();
th2.start();
th3.start();
th4.start();
th5.start();
}
}class Tc implements java.lang.Runnable{
static int pp=100;
static int count=0;
private int aa;
public Tc(int aa){
this.aa=aa;
}
public void run(){
while(pp>0){
synchronized(TimerContent.ss){
if(pp>0){
count++;
System.out.println("第"+aa+"个窗口,第"+count+"张票"+", "+pp);
pp--;
}
}
try{
Thread.sleep(1);
}catch(Exception e){
e.printStackTrace();
}
}
}
},当然上面也可以不用同步,将TimerContent.ss也可以改为自定的变量,执行前执行后的值变化一下