新手求教 多线程问题

Noctis_zhao 2014-07-03 08:21:31
代码如下:
class ThreadDemo1
{
public static void main(String[] args)
{
TestThread tt = new TestThread();
/*tt.start();
tt.start();
tt.start();
tt.start();*/
new Thread(tt). start();
new Thread(tt). start();
new Thread(tt). start();
new Thread(tt). start();
}
}
class TestThread implements Runnable //extends Thread
{
int tickets = 100;
String str = new String("");
public void run()
{
while (true)
{
synchronized(this)
{
if (tickets > 0)
{
try{Thread.sleep(10);}
catch(Exception e){}
System.out.println(Thread.currentThread().getName()+" is selling ticket" + tickets--);
}
}
}
/*for(int i=0;i<=100;i++)
{
sale();
}

}
public synchronized void sale()
{
if (tickets > 0)
{
try{Thread.sleep(100);}
catch(Exception e){}
System.out.println(Thread.currentThread().getName()+" is selling ticket" + tickets--);
}*/

}
}
为什么运行后会这样 四线程为什么变成一个了
...全文
490 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
u011643314 2014-07-23
  • 打赏
  • 举报
回复
引用 6 楼 guest6379 的回复:
[quote=引用 5 楼 rumlee 的回复:] [quote=引用 4 楼 commanager 的回复:] Thread.sleep 不会释放同步锁,而你的Thread.sleep在同步块中,不会释放锁,执行结束后,四个线程去竞争同步锁,其它线程有可能获取,但是他自身获取的几率很大(java线程竞争锁的概率是不是一样的需要研究。)让过想让其它线程获取锁,使用wait()等同步方法吧。
sleep执行结束后,四个线程竞争同步锁,自己获取的几率大。 你的这个说法是错误的。sleep不会释放锁,所以不存在你说的竞争的问题,该线程将会一直持有锁,直到释放锁为止。[/quote] 结果不一定是只有一个线程被执行,也许是2个,也可能是3个。 在我自己的i7机器上运行,只有1个线程打出结果了,但在同学的i3机器上跑了下,就会出现2,3个线程打出结果的情况。 还发现,如果更改Thread.sleep(1)的话,即使是i3的机器也只有1个线程打印出结果。 这个是什么原因呢?[/quote]可能是休眠时间问题,
lliiqiang 2014-07-23
  • 打赏
  • 举报
回复
因为共用一个RUnnable对象,实际上执行的是一个runnable对象的方法.
u014392535 2014-07-12
  • 打赏
  • 举报
回复
你就运行一次吧 多运行几次 因为你ticket才100随机性很大 代码是没有错的确实是4线程在执行 但是很可能在一个线程抢到执行权后别的线程还没抢到执行权就把ticket卖光了。 你可以吧ticket重置多点 或者多运行几遍
commanager 2014-07-11
  • 打赏
  • 举报
回复
引用 10 楼 lliiqiang 的回复:
多线程执行顺序是随机的.
多线程的执行顺序不一定是随机的。就是在低版本JDk的random一样,在获取大量随机数后,发现其分布竟然是不均匀的,后来,修改了这一个BUG,高版本JDK的随机数才真正意义上是公平的!
Noctis_zhao 2014-07-05
  • 打赏
  • 举报
回复
顺便问下 一个多进程 第一个进程结束后没有用wait挂起,会不会继续执行第一个进程而不转到下一个进程执行呢
藏于天地 2014-07-05
  • 打赏
  • 举报
回复
线程同步的问题:主要靠锁来实现,这里一定要保证锁的不同
Noctis_zhao 2014-07-05
  • 打赏
  • 举报
回复
感谢各位大大的指导
晓风吹雾 2014-07-04
  • 打赏
  • 举报
回复
还有 代码格式, 不然的话真的懒得看。
晓风吹雾 2014-07-04
  • 打赏
  • 举报
回复
线程的竞争导致这个问题 thread1,2,3 去竞争争夺锁的时候并没有竞争过thread0, 因为并没有让thread进行sleep 你的sleep 只是在加锁以后的sleep是没有任何作用的。 如果的在释放锁以后 sleep ,其他的thread才有可能得到锁 所以说代码改为

while (true) {
            synchronized (this) {
                if (tickets > 0) {
                    try {
                        Thread.sleep(10);
                    } catch (Exception e) {
                    }
                    System.out.println(Thread.currentThread().getName() + " is selling ticket"
                            + tickets--);
                }
            }
            
            try {
                Thread.sleep(10);
            } catch (Exception e) {
            }
百里马 2014-07-04
  • 打赏
  • 举报
回复
引用 5 楼 rumlee 的回复:
[quote=引用 4 楼 commanager 的回复:] Thread.sleep 不会释放同步锁,而你的Thread.sleep在同步块中,不会释放锁,执行结束后,四个线程去竞争同步锁,其它线程有可能获取,但是他自身获取的几率很大(java线程竞争锁的概率是不是一样的需要研究。)让过想让其它线程获取锁,使用wait()等同步方法吧。
sleep执行结束后,四个线程竞争同步锁,自己获取的几率大。 你的这个说法是错误的。sleep不会释放锁,所以不存在你说的竞争的问题,该线程将会一直持有锁,直到释放锁为止。[/quote] while循环的间隙会去竞争锁吧?
guest6379 2014-07-04
  • 打赏
  • 举报
回复
引用 5 楼 rumlee 的回复:
[quote=引用 4 楼 commanager 的回复:] Thread.sleep 不会释放同步锁,而你的Thread.sleep在同步块中,不会释放锁,执行结束后,四个线程去竞争同步锁,其它线程有可能获取,但是他自身获取的几率很大(java线程竞争锁的概率是不是一样的需要研究。)让过想让其它线程获取锁,使用wait()等同步方法吧。
sleep执行结束后,四个线程竞争同步锁,自己获取的几率大。 你的这个说法是错误的。sleep不会释放锁,所以不存在你说的竞争的问题,该线程将会一直持有锁,直到释放锁为止。[/quote]

while (true) {
    synchronized (this) { //  竞争锁,获得以后,加锁,进入同步块
        if (tickets > 0) {
            try {
                Thread.sleep(100);
            } catch (Exception e) {
            }
            System.out.println(Thread.currentThread().getName()
                    + " is selling ticket" + tickets--);
        }
    } // 结束同步块,释放锁,让其他线程又机会获得锁(线程1的同步块执行结束,其他线程都去竞争锁)
}
我同意sleep和锁没啥 关系,但是同步块是放在while下面的,所以,下一次while的时候,其他线程就有机会去竞争锁! 所以理论上是不会只有1个线程输出结果的,但是为什么在i7机器(或者调小sleep的时间)会很高的概率出现只有1个线程输出结果,这个我同意4楼,java一定有什么自己争夺锁的内部逻辑吧。
guest6379 2014-07-04
  • 打赏
  • 举报
回复
引用 5 楼 rumlee 的回复:
[quote=引用 4 楼 commanager 的回复:] Thread.sleep 不会释放同步锁,而你的Thread.sleep在同步块中,不会释放锁,执行结束后,四个线程去竞争同步锁,其它线程有可能获取,但是他自身获取的几率很大(java线程竞争锁的概率是不是一样的需要研究。)让过想让其它线程获取锁,使用wait()等同步方法吧。
sleep执行结束后,四个线程竞争同步锁,自己获取的几率大。 你的这个说法是错误的。sleep不会释放锁,所以不存在你说的竞争的问题,该线程将会一直持有锁,直到释放锁为止。[/quote] 结果不一定是只有一个线程被执行,也许是2个,也可能是3个。 在我自己的i7机器上运行,只有1个线程打出结果了,但在同学的i3机器上跑了下,就会出现2,3个线程打出结果的情况。 还发现,如果更改Thread.sleep(1)的话,即使是i3的机器也只有1个线程打印出结果。 这个是什么原因呢?
rumlee 2014-07-04
  • 打赏
  • 举报
回复
引用 4 楼 commanager 的回复:
Thread.sleep 不会释放同步锁,而你的Thread.sleep在同步块中,不会释放锁,执行结束后,四个线程去竞争同步锁,其它线程有可能获取,但是他自身获取的几率很大(java线程竞争锁的概率是不是一样的需要研究。)让过想让其它线程获取锁,使用wait()等同步方法吧。
sleep执行结束后,四个线程竞争同步锁,自己获取的几率大。 你的这个说法是错误的。sleep不会释放锁,所以不存在你说的竞争的问题,该线程将会一直持有锁,直到释放锁为止。
commanager 2014-07-04
  • 打赏
  • 举报
回复
Thread.sleep 不会释放同步锁,而你的Thread.sleep在同步块中,不会释放锁,执行结束后,四个线程去竞争同步锁,其它线程有可能获取,但是他自身获取的几率很大(java线程竞争锁的概率是不是一样的需要研究。)让过想让其它线程获取锁,使用wait()等同步方法吧。
rumlee 2014-07-04
  • 打赏
  • 举报
回复
四个线程用的是同一个Runnable对象,而且run方法中同步阻塞了,所以就会出现你的这种效果了。 把你的sleep改成wait试试看,你应该能够看到你要的效果。
lliiqiang 2014-07-04
  • 打赏
  • 举报
回复
多线程执行顺序是随机的.
rumlee 2014-07-04
  • 打赏
  • 举报
回复
引用 8 楼 u012345283 的回复:
[quote=引用 5 楼 rumlee 的回复:] [quote=引用 4 楼 commanager 的回复:] Thread.sleep 不会释放同步锁,而你的Thread.sleep在同步块中,不会释放锁,执行结束后,四个线程去竞争同步锁,其它线程有可能获取,但是他自身获取的几率很大(java线程竞争锁的概率是不是一样的需要研究。)让过想让其它线程获取锁,使用wait()等同步方法吧。
sleep执行结束后,四个线程竞争同步锁,自己获取的几率大。 你的这个说法是错误的。sleep不会释放锁,所以不存在你说的竞争的问题,该线程将会一直持有锁,直到释放锁为止。[/quote] while循环的间隙会去竞争锁吧?[/quote] 不好意思,你说的对,我没有注意到他把锁放在while循环内部了。

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧