java 中多线程问题?为什么最后输出的答案不是2000 b=1000有哪位大神详细分析一下两个线程之间怎么运行的吗?感激不尽

RATNG 2016-07-29 12:37:30
public class TT implements Runnable {
int b = 100;

public synchronized void m1() throws Exception{
b = 1000;
Thread.sleep(5000);
System.out.println("b = " + b);
}

public synchronized void m2() throws Exception {
Thread.sleep(2500);
b = 2000;
}

public void run() {
try {
m1();
} catch(Exception e) {
e.printStackTrace();
}
}

public static void main(String[] args) throws Exception {
TT tt = new TT();
Thread t = new Thread(tt);
t.start();

tt.m2();
System.out.println(tt.b);
}
}
...全文
220 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
soapyuki 2016-07-30
  • 打赏
  • 举报
回复
首先是synchronized修饰的方法,是同步的,这个锁,锁的是调用对象,main方法里面 Thread t1 = new Thread(tt); t1.setName("线程1"); t1.start(); tt.m2(); 在main方法中,JVM启动创建了一个主线程去调用main方法。 t1.start()方法首先是 start():首先启动了线程,然后再由 jvm去调用该线程的run()方法。 所以tt.m2()方法因为是main线程调用的,先启动,然后因为 m1方法和m2方法都是同步的,锁的对象是调用对象,都是同一个调用对象tt ,所以执行完m2方法后再执行m1。。 同样的, t1.start(); tt.m1(); 也是先启动下面的tt.m1()方法,然后再启动t1.start()对应的 run() m1()
soapyuki 2016-07-30
  • 打赏
  • 举报
回复

public class TT implements Runnable {
	int b = 100;
        int i = 0;
	public synchronized void m1() throws Exception {
		System.out.println(Thread.currentThread().getName()+"线程进入m1");
		b = 1000;
		Thread.sleep(5000);
		i++;
		System.out.println("m1.b="+ b +",i=" + i+"线程是:" + Thread.currentThread().getName());
		System.out.println("结束m1");
	}

	public synchronized void m2() throws Exception {
		System.out.println(Thread.currentThread().getName()+"线程进入m2");
		Thread.sleep(2500);
		b = 2000;
		System.out.println("m2.b=" + b +",i="+ i+"线程是:"+ Thread.currentThread().getName());
	}

	
	public void run() {
		try {
			System.out.println(Thread.currentThread().getName()+"开始执行run方法");
			m1();
		
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			System.out.println(Thread.currentThread().getName()+"执行run方法完毕");
		}
	}

	public static void main(String[] args) throws Exception {
		TT tt = new TT();
		Thread t1 = new Thread(tt);
		t1.setName("线程1");
		t1.start();
	
		tt.m1();
//		main线程进入m1
//		线程1开始执行run方法
//		m1.b=1000,i=1线程是:main
//		结束m1
//		线程1线程进入m1
//		m1.b=1000,i=2线程是:线程1
//		结束m1
//		线程1执行run方法完毕
		
		

//		tt.m2();
//		System.out.println(tt.b);
//		main线程进入m2
//		线程1开始执行run方法
//		m2.b=2000,i=0线程是:main
//		线程1线程进入m1
//		m1.b=1000,i=1线程是:线程1
//		结束m1
//		线程1执行run方法完毕

		
		
	}
}
这个是上面的运行结果,可以看看
RATNG 2016-07-30
  • 打赏
  • 举报
回复
引用 4 楼 soapyuki 的回复:
首先是synchronized修饰的方法,是同步的,这个锁,锁的是调用对象,main方法里面 Thread t1 = new Thread(tt); t1.setName("线程1"); t1.start(); tt.m2(); 在main方法中,JVM启动创建了一个主线程去调用main方法。 t1.start()方法首先是 start():首先启动了线程,然后再由 jvm去调用该线程的run()方法。 所以tt.m2()方法因为是main线程调用的,先启动,然后因为 m1方法和m2方法都是同步的,锁的对象是调用对象,都是同一个调用对象tt ,所以执行完m2方法后再执行m1。。 同样的, t1.start(); tt.m1(); 也是先启动下面的tt.m1()方法,然后再启动t1.start()对应的 run() m1()
引用 3 楼 soapyuki 的回复:

public class TT implements Runnable {
	int b = 100;
        int i = 0;
	public synchronized void m1() throws Exception {
		System.out.println(Thread.currentThread().getName()+"线程进入m1");
		b = 1000;
		Thread.sleep(5000);
		i++;
		System.out.println("m1.b="+ b +",i=" + i+"线程是:" + Thread.currentThread().getName());
		System.out.println("结束m1");
	}

	public synchronized void m2() throws Exception {
		System.out.println(Thread.currentThread().getName()+"线程进入m2");
		Thread.sleep(2500);
		b = 2000;
		System.out.println("m2.b=" + b +",i="+ i+"线程是:"+ Thread.currentThread().getName());
	}

	
	public void run() {
		try {
			System.out.println(Thread.currentThread().getName()+"开始执行run方法");
			m1();
		
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			System.out.println(Thread.currentThread().getName()+"执行run方法完毕");
		}
	}

	public static void main(String[] args) throws Exception {
		TT tt = new TT();
		Thread t1 = new Thread(tt);
		t1.setName("线程1");
		t1.start();
	
		tt.m1();
//		main线程进入m1
//		线程1开始执行run方法
//		m1.b=1000,i=1线程是:main
//		结束m1
//		线程1线程进入m1
//		m1.b=1000,i=2线程是:线程1
//		结束m1
//		线程1执行run方法完毕
		
		

//		tt.m2();
//		System.out.println(tt.b);
//		main线程进入m2
//		线程1开始执行run方法
//		m2.b=2000,i=0线程是:main
//		线程1线程进入m1
//		m1.b=1000,i=1线程是:线程1
//		结束m1
//		线程1执行run方法完毕

		
		
	}
}
这个是上面的运行结果,可以看看
引用 3 楼 soapyuki 的回复:

public class TT implements Runnable {
	int b = 100;
        int i = 0;
	public synchronized void m1() throws Exception {
		System.out.println(Thread.currentThread().getName()+"线程进入m1");
		b = 1000;
		Thread.sleep(5000);
		i++;
		System.out.println("m1.b="+ b +",i=" + i+"线程是:" + Thread.currentThread().getName());
		System.out.println("结束m1");
	}

	public synchronized void m2() throws Exception {
		System.out.println(Thread.currentThread().getName()+"线程进入m2");
		Thread.sleep(2500);
		b = 2000;
		System.out.println("m2.b=" + b +",i="+ i+"线程是:"+ Thread.currentThread().getName());
	}

	
	public void run() {
		try {
			System.out.println(Thread.currentThread().getName()+"开始执行run方法");
			m1();
		
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			System.out.println(Thread.currentThread().getName()+"执行run方法完毕");
		}
	}

	public static void main(String[] args) throws Exception {
		TT tt = new TT();
		Thread t1 = new Thread(tt);
		t1.setName("线程1");
		t1.start();
	
		tt.m1();
//		main线程进入m1
//		线程1开始执行run方法
//		m1.b=1000,i=1线程是:main
//		结束m1
//		线程1线程进入m1
//		m1.b=1000,i=2线程是:线程1
//		结束m1
//		线程1执行run方法完毕
		
		

//		tt.m2();
//		System.out.println(tt.b);
//		main线程进入m2
//		线程1开始执行run方法
//		m2.b=2000,i=0线程是:main
//		线程1线程进入m1
//		m1.b=1000,i=1线程是:线程1
//		结束m1
//		线程1执行run方法完毕

		
		
	}
}
这个是上面的运行结果,可以看看
引用 3 楼 soapyuki 的回复:

public class TT implements Runnable {
	int b = 100;
        int i = 0;
	public synchronized void m1() throws Exception {
		System.out.println(Thread.currentThread().getName()+"线程进入m1");
		b = 1000;
		Thread.sleep(5000);
		i++;
		System.out.println("m1.b="+ b +",i=" + i+"线程是:" + Thread.currentThread().getName());
		System.out.println("结束m1");
	}

	public synchronized void m2() throws Exception {
		System.out.println(Thread.currentThread().getName()+"线程进入m2");
		Thread.sleep(2500);
		b = 2000;
		System.out.println("m2.b=" + b +",i="+ i+"线程是:"+ Thread.currentThread().getName());
	}

	
	public void run() {
		try {
			System.out.println(Thread.currentThread().getName()+"开始执行run方法");
			m1();
		
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			System.out.println(Thread.currentThread().getName()+"执行run方法完毕");
		}
	}

	public static void main(String[] args) throws Exception {
		TT tt = new TT();
		Thread t1 = new Thread(tt);
		t1.setName("线程1");
		t1.start();
	
		tt.m1();
//		main线程进入m1
//		线程1开始执行run方法
//		m1.b=1000,i=1线程是:main
//		结束m1
//		线程1线程进入m1
//		m1.b=1000,i=2线程是:线程1
//		结束m1
//		线程1执行run方法完毕
		
		

//		tt.m2();
//		System.out.println(tt.b);
//		main线程进入m2
//		线程1开始执行run方法
//		m2.b=2000,i=0线程是:main
//		线程1线程进入m1
//		m1.b=1000,i=1线程是:线程1
//		结束m1
//		线程1执行run方法完毕

		
		
	}
}
这个是上面的运行结果,可以看看
谢谢
RATNG 2016-07-30
  • 打赏
  • 举报
回复
线程1开始执行run方法 线程1线程进入m1 m1.b=1000,i=1线程是:线程1 结束m1 线程1执行run方法完毕
引用 4 楼 soapyuki 的回复:
首先是synchronized修饰的方法,是同步的,这个锁,锁的是调用对象,main方法里面 Thread t1 = new Thread(tt); t1.setName("线程1"); t1.start(); tt.m2(); 在main方法中,JVM启动创建了一个主线程去调用main方法。 t1.start()方法首先是 start():首先启动了线程,然后再由 jvm去调用该线程的run()方法。 所以tt.m2()方法因为是main线程调用的,先启动,然后因为 m1方法和m2方法都是同步的,锁的对象是调用对象,都是同一个调用对象tt ,所以执行完m2方法后再执行m1。。 同样的, t1.start(); tt.m1(); 也是先启动下面的tt.m1()方法,然后再启动t1.start()对应的 run() m1()
我仔细看了好久。终于明白两个进程怎么运行的了。O(∩_∩)O谢谢
RATNG 2016-07-29
  • 打赏
  • 举报
回复
一开始不应该执行m1方法吗
anakin_feng 2016-07-29
  • 打赏
  • 举报
回复
因为两个方法是同一个锁,所以m1(),m2()方法不能同时调用。 这个结果是因为,先进入了m2方法,所以m1一直等待,当m2执行完成,马上执行了m1, 至于m1和System.out.println(tt.b);执行顺序,感觉会先执行m1,这个我不确定

62,628

社区成员

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

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