黑马程序员技术交流社区
标题:
关于线程的问题 求解求解
[打印本页]
作者:
che201311
时间:
2013-11-21 22:27
标题:
关于线程的问题 求解求解
public class Ticket {
public static void main(String[] args){
Loket l1 = new Loket(1);
Loket l2 = new Loket(2);
Loket l3 = new Loket(3);
Loket l4 = new Loket(4);
Loket l5 = new Loket(5);
Thread t1 = new Thread(l1);
Thread t2 = new Thread(l2);
Thread t3 = new Thread(l3);
Thread t4 = new Thread(l4);
Thread t5 = new Thread(l5);
t1.start();
t2.start();
t3.start();
t4.start();
t5.start();
}
}
class Loket implements Runnable{
static int ticketnum =100;
static int count = 0;
int a;
Loket(int a){
this.a = a;
}
public synchronized void run() {
while(ticketnum>0){
System.out.println("第"+ a+"个售票窗口售出:" +"第"+(++count)+
"张票");
ticketnum --;
}
try{
Thread.sleep(1);
}catch(InterruptedException e){
e.printStackTrace();
}
}
}
我设的静态变量ticketnum是100可是最后怎么count会变成104呢,按说应该也是100啊,如果把while换成if就只出来5张票,如果把下面的Thread.sleep()放到while循环中为什么又不到100张了,就是在90多张的地方就停住了。还有加锁到底应该在什么地方加锁啊,我加的synchronized地方对不对啊?菜鸟求大神指导啊
作者:
″先森丶玹°
时间:
2013-11-21 22:47
你在while循环下面加上一句:
if(count<100)
就行了。
你count并未定义++的上限,所以会出现101 102....这种票。
作者:
che201311
时间:
2013-11-21 22:55
是这个道理
作者:
qw无语
时间:
2013-11-21 23:04
首先.你的synchronized在写run()上
如果成果,应该只有一个线程把所有票卖挖.
但是结果,所有线程都卖出票了,所以synchronize没有成功.
run()方法这样写:
public void run() {
while (ticketnum > 0) {
synchronized (Loket.class) {
if (ticketnum > 0) {
System.out.println("第" + a + "个售票窗口售出:" + "第" + (++count)
+ "张票");
ticketnum--;
}
}
}
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
在里面再判断一次是因为可能在
所有线程while (ticketnum > 0)在这判断完可能被抢去执行权.
在没有--之前都在锁前,所以再加次判断.
作者:
唐志海
时间:
2013-11-21 23:45
当多条语句在操做同一个现场的共享数据,一个线程对多条语句只执行了一部分,另外一线程参与
执行,造成共享数据的错误。
作者:
freehiker
时间:
2013-11-21 23:50
public class Ticket {
public static void main(String[] args) {
// TODO Auto-generated method stub
new Thread(new Window()).start();
new Thread(new Window()).start();
new Thread(new Window()).start();
new Thread(new Window()).start();
new Thread(new Window()).start();
new Thread(new Window()).start();
new Thread(new Window()).start();
new Thread(new Window()).start();
}
}
class Window implements Runnable {
static int count = 1;
public void run(){
while(count<=10){
synchronized(Window.class){
if(count<=10){
System.out.println(Thread.currentThread().getName()+"卖出了第"+count+"张票");
count++;
}
}
}
}
}
复制代码
作者:
smileven
时间:
2013-11-22 01:18
(1)为什么count变成104:
第一你的多线程操作同一份数据用的不是同一把锁,所以当一个线程进入同步代码块等待时,其他线程也可以进入同步代码块,会造成线程安全问题。
因为线程结束的控制条件是ticketnum=0;也就是说只有ticketnum>0的时候,t1,t2,t3,t4,t5才可以进入同步代码块。
所以你的锁应该在while( ticketnum > 0)里面。
如果你这样写:当一个线程进入同步代码块,刚好判断完ticketnum的值为1,此线程挂在这儿。
此时又有新的线程进入同步代码块,判断ticketnum == 1也进入了同步代码块。
这样就是多个线程卖最后一张票,但是只有一张票,所以会出现负数票,count也就大于100了。
(2)while换成if就出来5张票:
因为主线程把t1,t2,t3,t4,t5开启之后,它们各自都卖了一张票,然后t1,t2,t3,t4,t5线程都已经结束了。
因为没有循环去卖剩下的票,if()只是一次判断条件,每个线程都判断一次,然后结束了线程。
(3)Thread.sleep()放在while()中卖不到100张票:
这个你多试几次,其实不是卖不到100张。我试的结果是可以买到90多张,可以买到100张,也可以买到101张。
这都是线程安全出问题造成的。
解决办法:
(1)t1,t2,t3,t4,t5五个线程操作ticketnum这一份数据必须使用同一把锁。
(2)进入同步代码的条件应该放在锁的外面。
具体代码楼上写的很好了,参考一下~~
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2