论坛首页 Java企业应用论坛

关于多线程的一些问题

浏览 8292 次
精华帖 (0) :: 良好帖 (1) :: 新手帖 (3) :: 隐藏帖 (0)
作者 正文
   发表时间:2011-05-10   最后修改:2011-05-10
对于多线程,我有了解一些,但最近在使用中碰到一个问题,按我的思维,以下程序不应该那样执行,但结果还是出人意料。
我个人理解,在线程a中调用了t对象的methodA方法,这个方法获取了x变量的锁,然后让a线程休眠30秒,此时a线程应该是没有释放x对象锁,那么主线程调用methodB方法中对x对象操作应该被阻塞的。但结果却没有阻塞,执行了对x的操作,这里为什么a线程中没有锁住x对象?
-------------------
针对各位的回答,我作一下,个人总结,分析不对的,请轻拍:
首先x对象锁确实是被a线程获取了,那为什么t.methodB中对x的操作仍然可以操作呢,是因为,在t.methodB中对x对象操作时,并没有请求需要x对象锁,所以是可以操作x的,此时如果在t.methodB中作如下处理:
    public void methodB() {
        synchronized(x){
            x-=1;
            System.out.println("执行B方法");
            System.out.println("x在B方法:"+x);
        }
    }

那么,此时就是再次请求x对象锁,前面说了x对象锁已经被a线程获取了,一个对象只能有一个锁,这里主线程想再获取x对象锁就获取不到,就被阻塞。
--------------------------------
package com.ruijie;

public class TestMain {

    /**	
     * <p>Description:              </p>
     * <p>Create Time: 2011-5-10   </p>
     * @author Semmy
     * @param args
     * @throws InterruptedException 
     */
    public static void main(String[] args) throws InterruptedException {
        Test t=new Test();
        Thread a=new Thread(new ThreadA(t));
        a.start();
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        t.methodB();
    }

}

class ThreadA implements Runnable{
    Test t;
    public ThreadA(Test t) {
        this.t=t;
    }

    public void run() {
        
        try {
            System.out.println("线程A执行,正在睡眠。。。。");
            t.methodA("线程A调用");
            System.out.println("线程A执行,完成睡眠。。。。");
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    
}

class Test{
    private Integer x=new Integer(10);
    public  void methodA(String str) throws InterruptedException {
            synchronized(x){
                System.out.println(str);
                System.out.println("x在A中值为:"+x);
                Thread.sleep(30000);
                x-=1;
                System.out.println("x在A中值为:"+x);
            }
    }
    public void methodB() {
        x-=1;
        System.out.println("执行B方法");
        System.out.println("x在B方法:"+x);
    }
}


执行结果:
-----------------------------
线程A执行,正在睡眠。。。。
线程A调用
x在A中值为:10
执行B方法
x在B方法:9
x在A中值为:8
线程A执行,完成睡眠。。。。
   发表时间:2011-05-10  
什么就没人回复啊,
0 请登录后投票
   发表时间:2011-05-10  
没有看见你的MethodB中有锁
0 请登录后投票
   发表时间:2011-05-10  
java_user 写道
没有看见你的MethodB中有锁

MethodB是没有锁,但在methodA中对x进行锁了,
0 请登录后投票
   发表时间:2011-05-10  
线程执行methodB中,要对x对象进行操作,是不是应该发现,x的锁被别的线程获取了,应该在methodB中阻塞,等待x对象锁啊?
0 请登录后投票
   发表时间:2011-05-10  
你并没有声明在methodB中需要获得x的锁,所以methodB照常执行
0 请登录后投票
   发表时间:2011-05-10  
t.methodB();又不要求获取锁x,为什么要阻塞?


照楼主这个思维,可以把methodA的synchronied(x)给去掉,然后用意念给methodA对x加锁,这样也可以用意念对methodB()给x加锁了
0 请登录后投票
   发表时间:2011-05-10  
对哦,谢谢两位,methodB中没有用synchronied,所以没有对x进行请求锁。
0 请登录后投票
   发表时间:2011-05-10  
你Asleep30秒的时候主线程sleep2秒已经结束了,继续执行调用方法t.methodB了呀。
0 请登录后投票
   发表时间:2011-05-10   最后修改:2011-05-10
2点疑问:
1.methodB()是不是需要加synchronized(x),这个肯定是要的
2.x-=1;这个操作会不会破坏对象锁?(个人感觉会的)
如果把x-=1;放到Thread.sleep(30000);上面,那么methodB()中的synchronized(x)不是原来x的锁了。
呵呵,自己对锁这块概念不是很清晰。
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics