黑马程序员技术交流社区

标题: 请大神帮忙看看这个多线程代码 [打印本页]

作者: Fangjie    时间: 2016-6-7 13:30
标题: 请大神帮忙看看这个多线程代码
我加了同步锁的,怎么结果还是不对!

作者: 我有上将潘凤    时间: 2016-6-7 13:41
你想要什么结果?
作者: 何亚辉    时间: 2016-6-7 13:43
你试试看把下面的if判断写到同步锁的第一句话,,
作者: Fangjie    时间: 2016-6-7 13:50
我有上将潘凤 发表于 2016-6-7 13:41
你想要什么结果?

顺序结果,就是从70一自减到0
作者: Fangjie    时间: 2016-6-7 13:52
我有上将潘凤 发表于 2016-6-7 13:41
你想要什么结果?

顺序结果,就是从70一直自减到0
作者: Fangjie    时间: 2016-6-7 13:54
何亚辉 发表于 2016-6-7 13:43
你试试看把下面的if判断写到同步锁的第一句话,,

试了的,还是不行,用了多线程,就不能保证数据的同步了吗
作者: 车前子008    时间: 2016-6-7 14:06
锁上的不对 锁必须是唯一的  你的这个变量是共享的呀  用this  或者Shangche.class试一试
作者: 何亚辉    时间: 2016-6-7 14:12
本帖最后由 何亚辉 于 2016-6-7 14:21 编辑

package com.heima.IO;

import java.io.IOException;
import java.util.Scanner;
import java.util.Set;
import java.util.TreeMap;

public class Day1_ClassTest2 {
        public static void main(String[] args) throws IOException {
                shangche sc = new shangche();
                new Thread(sc, "线程一").start();
                new Thread(sc, "线程二").start();

        }

}

class shangche implements Runnable {

        int person = 70;
        Object o = new Object();

        public void run() {
                while (person>0) {
                        synchronized (o) {
                                if (person <= 0) {
                                        return;
                                }
                                System.out.println(Thread.currentThread().getName() + "自减"+--person);
                        }

                }
        }
}

作者: 何亚辉    时间: 2016-6-7 14:15
本帖最后由 何亚辉 于 2016-6-7 14:23 编辑

问题就是, 你这个Person既做了变量, 又做了锁 .,.  这个锁一直在改变

我试了下换成另一个不变的锁,,     就不存在这个问题了

作者: lifeiwangyue    时间: 2016-6-7 14:40
persons对象的数值一直在改变的啊  锁对象不是一个了    换个吧
作者: Fangjie    时间: 2016-6-7 15:55
车前子008 发表于 2016-6-7 14:06
锁上的不对 锁必须是唯一的  你的这个变量是共享的呀  用this  或者Shangche.class试一试 ...

谢谢,试了下,是这个原因,但是数据还是有点不同步,会出现负数,不是我的循环条件是>0的,最后到了另一个线程的时候就会出现负数
作者: Fangjie    时间: 2016-6-7 15:56
何亚辉 发表于 2016-6-7 14:15
问题就是, 你这个Person既做了变量, 又做了锁 .,.  这个锁一直在改变

我试了下换成另一个不变的锁,,      ...

试了下,数据顺序的问题解决了,但是最后的一个线程会出现负数,我的结束条件是>0的,怎么另一个线程没有按条件来。
作者: Fangjie    时间: 2016-6-7 15:59
何亚辉 发表于 2016-6-7 14:15
问题就是, 你这个Person既做了变量, 又做了锁 .,.  这个锁一直在改变

我试了下换成另一个不变的锁,,      ...

试了下,数据顺序的问题解决了,但是最后的一个线程会出现负数,我的结束条件是>0的,怎么另一个线程没有按条件来。
作者: Fangjie    时间: 2016-6-7 16:03

试了下,是这个问题,但是最后一个线程执行的时候,怎么会是负数,它没有按照while(persons>0)的这个条件执行啊

作者: jijiangrui    时间: 2016-6-7 17:18
Fangjie 发表于 2016-6-7 16:03
试了下,是这个问题,但是最后一个线程执行的时候,怎么会是负数,它没有按照while(persons>0)的这个条件 ...

你是先判断才获取锁,肯定会出现这情况,你把判断放同步代码块里就 没事了
作者: Fangjie    时间: 2016-6-8 20:48
jijiangrui 发表于 2016-6-7 17:18
你是先判断才获取锁,肯定会出现这情况,你把判断放同步代码块里就 没事了  ...

是啊,这样是可以,但是这种写法,不能多线程,可能这就是这道题的难点所在。
作者: Fangjie    时间: 2016-6-8 20:49


作者: 车前子008    时间: 2016-6-8 23:55
换成persons--
作者: Fangjie    时间: 2016-6-9 07:24
车前子008 发表于 2016-6-8 23:55
换成persons--

这样还是只能单线程。




作者: 车前子008    时间: 2016-6-9 11:56
        class Shangche implements Runnable{
               
        static int persons = 70;
        public void run(){
                while(true){
                synchronized (Shangche.class){
                if(persons>0){
                        System.out.println(Thread.currentThread().getName()+persons--);
                       
                }
                }
                }
                }
        }
作者: Fangjie    时间: 2016-6-9 18:44
车前子008 发表于 2016-6-9 11:56
class Shangche implements Runnable{
               
        static int persons = 70;

试了一下,这种方法虽然能保证数据同步,如果在while上面加锁,最后都是只一个线程走完,可以在run方法里调用其它的线程吗
作者: Fangjie    时间: 2016-6-12 06:54
车前子008 发表于 2016-6-9 11:56
class Shangche implements Runnable{
               
        static int persons = 70;

问题解决了,这种写法可行!
        public static void main(String[] args) throws InterruptedException {
                        ByBus b = new ByBus();
                        Thread t1 = new Thread(b, "线程一");
                        Thread t2 = new Thread(b, "线程二");
                        t1.start();
                        t2.start();
                        t1.join();
                        t2.join();
                        System.out.println("执行完毕");
                }
        }

        class ByBus implements Runnable {
               
                public static int  persons = 70;
                public void run() {               
                        while (true) {
                        synchronized (ByBus.class) {
                                if(persons<=0)
                                        break;
                                        System.out.println(Thread.currentThread().getName() +-- persons);
                                }
                        }                               
                }
作者: 18343105017    时间: 2016-6-18 21:22
把锁里的 Person换成this           synchronize(this)

作者: 18343105017    时间: 2016-6-18 21:25
写错了  是  synchronized(this)
作者: chengxiankun    时间: 2016-6-18 22:03
按照你代码的意思,感觉没有问题。。。。。
作者: 善良的死神达乐    时间: 2016-6-18 22:18
何亚辉 发表于 2016-6-7 14:12
package com.heima.IO;

import java.io.IOException;

六六六。。。




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