神牛进,多线程问题!!!

AI传道士 2014-05-15 05:12:55
package com.zken.pkg;

public class MultiThread implements Runnable {
private String name;

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public void run() {
if (this.getName().equals("1")) {
m1();
}else if(this.getName().equals("2")){
m2();
}
}

private synchronized void m1() {
try {
Thread.sleep(1000 * 10);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("m1::::"+this.getName());
}

private void m2() {
System.out.println("m2::::"+this.getName());
}

public static void main(String[] args) {
MultiThread multiThread = new MultiThread();
Thread thread1 = new Thread(multiThread);
multiThread.setName("1");
thread1.start();
Thread thread2 = new Thread(multiThread);
multiThread.setName("2");
thread2.start();
}
}

输出结果是:
m2::::2
m2::::2
为什么两次执行的都是m2方法?不应该呀????

...全文
591 40 打赏 收藏 转发到动态 举报
写回复
用AI写文章
40 条回复
切换为时间正序
请发表友善的回复…
发表回复
AI传道士 2014-05-16
  • 打赏
  • 举报
回复
引用 17 楼 pengxiao618 的回复:
撼地神牛跳大五杀
不懂~~~~~~~~~~~~~
AI传道士 2014-05-16
  • 打赏
  • 举报
回复
引用 18 楼 ljl434841 的回复:
如此多人,神牛?跳大啊!
朋友有什么高见,不妨交流交流啊~~~~~~~~~~~~~~~~~
AI传道士 2014-05-16
  • 打赏
  • 举报
回复
引用 16 楼 fbpcchen 的回复:
public class Bank implements Runnable{
	private int money = 20000;
	
	public int getMoney() {
		return money;
	}
	public void setMoney(int money) {
		this.money = money;
	}
	private String matipulate;
	
	public String getMatipulate() {
		return matipulate;
	}
	public void setMatipulate(String matipulate) {
		this.matipulate = matipulate;
	}
	public void run() {
		if(matipulate.equals("get"))
			getMoney(1000);
		if(matipulate.equals("save"))
			saveMoney(1000);
		
	}
	private int getMoney(int num){
		this.money -= num;
		System.out.println("from bank get money:" + num);
		System.out.println(getMoney());
		return num;
	}
	private void saveMoney(int num){
		this.money += num;
		System.out.println("to bank save money:" + num);
		System.out.println(getMoney());
	}
	public static void main(String[] args) {
		Bank bank = new Bank();
		Thread t1 = new Thread(bank);
		Thread t2 = new Thread(bank);
		bank.setMatipulate("get");
		t1.start();
		bank.setMatipulate("save");
		t2.start();
		System.out.println(bank.getMoney());
		
	}

}
楼主运行一下这个程序,多运行几次,你就知道线程之间的执行顺序了。有点类似于多道程序处理机在没有引入进程之前,并发程序的运行会产生间断性、不可再现性和失去封闭性的特点
跑了几次,得出了一个结论,不知正确与否:主线程跑的比子线程要快很多,也就是说主线程的优先级要高于子线程的,不知我这样理解可有问题?????????
绝对在乎妮 2014-05-16
  • 打赏
  • 举报
回复
如此多人,神牛?跳大啊!
  • 打赏
  • 举报
回复
撼地神牛跳大五杀
fbpcchen 2014-05-16
  • 打赏
  • 举报
回复
public class Bank implements Runnable{
	private int money = 20000;
	
	public int getMoney() {
		return money;
	}
	public void setMoney(int money) {
		this.money = money;
	}
	private String matipulate;
	
	public String getMatipulate() {
		return matipulate;
	}
	public void setMatipulate(String matipulate) {
		this.matipulate = matipulate;
	}
	public void run() {
		if(matipulate.equals("get"))
			getMoney(1000);
		if(matipulate.equals("save"))
			saveMoney(1000);
		
	}
	private int getMoney(int num){
		this.money -= num;
		System.out.println("from bank get money:" + num);
		System.out.println(getMoney());
		return num;
	}
	private void saveMoney(int num){
		this.money += num;
		System.out.println("to bank save money:" + num);
		System.out.println(getMoney());
	}
	public static void main(String[] args) {
		Bank bank = new Bank();
		Thread t1 = new Thread(bank);
		Thread t2 = new Thread(bank);
		bank.setMatipulate("get");
		t1.start();
		bank.setMatipulate("save");
		t2.start();
		System.out.println(bank.getMoney());
		
	}

}
楼主运行一下这个程序,多运行几次,你就知道线程之间的执行顺序了。有点类似于多道程序处理机在没有引入进程之前,并发程序的运行会产生间断性、不可再现性和失去封闭性的特点
fbpcchen 2014-05-16
  • 打赏
  • 举报
回复
如果两个线程之间没有使用睡眠阻塞,那么在使用的同一个Runnable对象里面的nama变量赋值都为“2”,所以都是执行的m2方法
AI传道士 2014-05-16
  • 打赏
  • 举报
回复
引用 13 楼 zkn_CS_DN_2013 的回复:
[quote=引用 8 楼 yyfhz 的回复:] 问题在于LZ的代码用了同一个MultiThread对象来生成2个线程,导致对象MultiThread里面的变量出现同步问题。 LZ可以试着将代码改成

    public static void main(String[] args) {
        MultiThread multiThread = new MultiThread();
        Thread thread1 = new Thread(multiThread);
        multiThread.setName("1");
        thread1.start();
        MultiThread multiThread2 = new MultiThread();
        Thread thread2 = new Thread(multiThread2);
        multiThread2.setName("2");
        thread2.start();
    }
就会正常了。
[/quote] 我不是要求结果正常就行了,关键是想要明白主线程和子线程之间的关系和执行机制~~~~~~~~~
AI传道士 2014-05-16
  • 打赏
  • 举报
回复
引用 8 楼 yyfhz 的回复:
问题在于LZ的代码用了同一个MultiThread对象来生成2个线程,导致对象MultiThread里面的变量出现同步问题。 LZ可以试着将代码改成

    public static void main(String[] args) {
        MultiThread multiThread = new MultiThread();
        Thread thread1 = new Thread(multiThread);
        multiThread.setName("1");
        thread1.start();
        MultiThread multiThread2 = new MultiThread();
        Thread thread2 = new Thread(multiThread2);
        multiThread2.setName("2");
        thread2.start();
    }
就会正常了。
AI传道士 2014-05-16
  • 打赏
  • 举报
回复
引用 11 楼 xuebichongkafei 的回复:
[quote=引用 楼主 zkn_CS_DN_2013 的回复:]
package com.zken.pkg;

public class MultiThread implements Runnable {
	private String name;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public void run() {
		if (this.getName().equals("1")) {
			m1();
		}else if(this.getName().equals("2")){
			m2();
		}
	}

	private synchronized void m1() {
		try {
			Thread.sleep(1000 * 10);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println("m1::::"+this.getName());
	}

	private void m2() {
		System.out.println("m2::::"+this.getName());
	}

	public static void main(String[] args) {
		MultiThread multiThread = new MultiThread();
		Thread thread1 = new Thread(multiThread);
		multiThread.setName("1");
		thread1.start();
		Thread thread2 = new Thread(multiThread);
		multiThread.setName("2");
		thread2.start();
	}
}
输出结果是: m2::::2 m2::::2 为什么两次执行的都是m2方法?不应该呀????
楼上加睡眠可以出现不同情况. 楼主这种情况的出现应该是,主线程执行代码速度很快执行过去(与个人电脑配置有关系),开启了两个线程,那么主线程一瞬间执行完代码,这时候name已经覆盖了上一次的赋值,成为了2,,直到主线程结束后,另外两个线程才抢到执行权.所以两个线程分别抢到执行全的时候,name都等于2,当然两字都是执行m2,name为2了. 不知道这种表达,楼主能否明白[/quote] 嗯嗯,同意!!!!!
AI传道士 2014-05-16
  • 打赏
  • 举报
回复
引用 39 楼 mybeta 的回复:
[quote=引用 33 楼 zkn_CS_DN_2013 的回复:] [quote=引用 29 楼 mybeta 的回复:] 因为是同一个Runnable,第一个线程虽然调用了start(),但可能还没开始执行,接下来第二个线程又把这个Runable的name改变了,然后两个线程开始执行run方法,这样是不是会出现你的情况呢
嗯,好,简单明了,就是线程同步问题,你对主线程和子线程之间的关心有什么独到的见解吗?不妨给大家分享一下哈~~~~~~~~~~~~[/quote] 我觉得你这个不是子线程和主线程的问题,只是单纯的两个线程之间的问题。你这里相当于用两个线程操作同一个对象,所以出现的问题。我不知道你要测什么啊,那个如果是要测试是哪个线程在执行哪个方法,可以设置Thread的name。[/quote] 怎么可能是两个单纯两个线程之间的关系?!!!那两个子线程都是由主线程main创建的,跟线程之间争抢cpu资源有关,我主要想测试一下线程并发时执行顺序和线程之间的关系问题,以及深入理解一下cpu是分配时间片给线程的。。不过,看了许多网上的文章以及大家积极的回答和帮助,我现在已经理解的差不多了,感谢》》》》
mybeta 2014-05-16
  • 打赏
  • 举报
回复
引用 33 楼 zkn_CS_DN_2013 的回复:
[quote=引用 29 楼 mybeta 的回复:] 因为是同一个Runnable,第一个线程虽然调用了start(),但可能还没开始执行,接下来第二个线程又把这个Runable的name改变了,然后两个线程开始执行run方法,这样是不是会出现你的情况呢
嗯,好,简单明了,就是线程同步问题,你对主线程和子线程之间的关心有什么独到的见解吗?不妨给大家分享一下哈~~~~~~~~~~~~[/quote] 我觉得你这个不是子线程和主线程的问题,只是单纯的两个线程之间的问题。你这里相当于用两个线程操作同一个对象,所以出现的问题。我不知道你要测什么啊,那个如果是要测试是哪个线程在执行哪个方法,可以设置Thread的name。
AI传道士 2014-05-16
  • 打赏
  • 举报
回复
我再声明一下啊,提问的问题简单还是复杂不重要,重要的是隐藏在其中深层次的原理,希望可以通过简单的例子引起大家的热烈讨论,进而延伸到更深层次的领域,各自说出自己的理解和看法,请大家不要拍砖啊!~~~~~~~~~~~
AI传道士 2014-05-16
  • 打赏
  • 举报
回复
引用 35 楼 u013646870 的回复:
真的有牛牛牛牛牛人唉。
必须的,高手都在民间,民间的高手都在网上!!!网上的高手都在csdn
AI传道士 2014-05-16
  • 打赏
  • 举报
回复
引用 32 楼 qq331077064 的回复:
你这个问题需要神牛吗? multiThread.setName("2");执行的时候,前面一个线程没有执行到 if (this.getName().equals("1")) { 如果要研究多线程和并发,可以研究 wait(),notify(),ThreadPoolExecutor,BlockingQueue,Semaphore,Barrier,Latch,ReentrantLock
嗯,不好意思啊,本人水平太次。。。请问你是如何理解java中的同步和数据库中锁的机制的??????????????????
u013646870 2014-05-16
  • 打赏
  • 举报
回复
真的有牛牛牛牛牛人唉。
AI传道士 2014-05-16
  • 打赏
  • 举报
回复
还有一个问题哈,各位神牛是如何理解java中的sychronized同步和数据库中锁的概念的,我觉得它们之间是很相似的,但我不能系统完整的表达出它们之间的关系,各位神牛有什么高见,请不吝赐教啊~~~~~~~~~~~~~~~~~~~
AI传道士 2014-05-16
  • 打赏
  • 举报
回复
引用 29 楼 mybeta 的回复:
因为是同一个Runnable,第一个线程虽然调用了start(),但可能还没开始执行,接下来第二个线程又把这个Runable的name改变了,然后两个线程开始执行run方法,这样是不是会出现你的情况呢
嗯,好,简单明了,就是线程同步问题,你对主线程和子线程之间的关心有什么独到的见解吗?不妨给大家分享一下哈~~~~~~~~~~~~
郑涛 2014-05-16
  • 打赏
  • 举报
回复
你这个问题需要神牛吗? multiThread.setName("2");执行的时候,前面一个线程没有执行到 if (this.getName().equals("1")) { 如果要研究多线程和并发,可以研究 wait(),notify(),ThreadPoolExecutor,BlockingQueue,Semaphore,Barrier,Latch,ReentrantLock
AI传道士 2014-05-16
  • 打赏
  • 举报
回复
感谢大家热情的回答,如有兴趣的话,可以参考下这篇文章: http://blog.csdn.net/it_man/article/details/7196645
加载更多回复(20)

62,614

社区成员

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

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