多线程大牛请进!

palettezwl 2013-09-16 09:03:15
小弟初试多线程就碰壁了。恳求大牛指点迷津。问题如下:
1.任务类:
public class Task implements Runnable{
private static int id=0;
private final int threadID=id++;

public Task(){
}
public void run(){
System.out.println("threadID="+threadID);
System.out.println("id="+id);
}
}
2.程序入口:
public class APPMain {
public static void main(String[] args){
ExecutorService es=Executors.newFixedThreadPool(1000);
for(int i=0;i<10;i++){
es.execute(new Task());
}
es.shutdown();
}
}
3.Eclipse中一次执行的结果:
threadID=0
id=5
threadID=1
id=10
threadID=2
threadID=3
id=10
threadID=5
id=10
threadID=7
id=10
threadID=6
id=10
threadID=8
id=10
threadID=4
id=10
id=10
threadID=9
id=10
4.跪求大牛指点各种道理。为什么id没有得到同步,ThreadID却得到了同步?
...全文
414 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
骑士的崛起 2013-11-19
  • 打赏
  • 举报
回复
不结贴是个挺烦的事情~~~
GP0071 2013-11-19
  • 打赏
  • 举报
回复
引用 7 楼 klov001 的回复:
[quote=引用 6 楼 u010926176 的回复:] 上面说的都有些道理,我整理了下大家的意见。 1、id这个变量是一个共享资源,所谓“共享资源”,指的是多个线程可以同时访问的数据结构、文件等信息实体。 2、你这段程序可以分为2段来看,一段是运算,一段是输出。 3、你代码中开启了10个线程访问共享资源id,对他进行运算。当第8个线程运算后。 4、第6个和第7个线程运行到输出,但是此时id已经被第8个线程重新计算为9,所以第6个和第7个线程输出的结果是9。 代码做了下改动,应该有更好的方法。请参考
package com.test;

public class Task implements Runnable {
	private static int id = 0;
	private int threadID = 0;
	public Task() {
	}

	public void run() {
		synchronized(this){
			threadID = id;
			System.out.println("id=" + id++);
			System.out.println("threadID=" + threadID);
		}
	}
}
那岂不是会这样啊:10个实力new 好了,但是10个线程执行顺序不确定,而id会递增顺序输出啊...? 还没代码验证。[/quote]
引用 7 楼 klov001 的回复:
[quote=引用 6 楼 u010926176 的回复:] 上面说的都有些道理,我整理了下大家的意见。 1、id这个变量是一个共享资源,所谓“共享资源”,指的是多个线程可以同时访问的数据结构、文件等信息实体。 2、你这段程序可以分为2段来看,一段是运算,一段是输出。 3、你代码中开启了10个线程访问共享资源id,对他进行运算。当第8个线程运算后。 4、第6个和第7个线程运行到输出,但是此时id已经被第8个线程重新计算为9,所以第6个和第7个线程输出的结果是9。 代码做了下改动,应该有更好的方法。请参考
package com.test;

public class Task implements Runnable {
	private static int id = 0;
	private int threadID = 0;
	public Task() {
	}

	public void run() {
		synchronized(this){
			threadID = id;
			System.out.println("id=" + id++);
			System.out.println("threadID=" + threadID);
		}
	}
}
那岂不是会这样啊:10个实力new 好了,但是10个线程执行顺序不确定,而id会递增顺序输出啊...? 还没代码验证。[/quote] 嗯 这么写完后 间接的就编程了 串行的了。
  • 打赏
  • 举报
回复
引用 6 楼 u010926176 的回复:
上面说的都有些道理,我整理了下大家的意见。 1、id这个变量是一个共享资源,所谓“共享资源”,指的是多个线程可以同时访问的数据结构、文件等信息实体。 2、你这段程序可以分为2段来看,一段是运算,一段是输出。 3、你代码中开启了10个线程访问共享资源id,对他进行运算。当第8个线程运算后。 4、第6个和第7个线程运行到输出,但是此时id已经被第8个线程重新计算为9,所以第6个和第7个线程输出的结果是9。 代码做了下改动,应该有更好的方法。请参考
package com.test;

public class Task implements Runnable {
	private static int id = 0;
	private int threadID = 0;
	public Task() {
	}

	public void run() {
		synchronized(this){
			threadID = id;
			System.out.println("id=" + id++);
			System.out.println("threadID=" + threadID);
		}
	}
}
那岂不是会这样啊:10个实力new 好了,但是10个线程执行顺序不确定,而id会递增顺序输出啊...? 还没代码验证。
GP0071 2013-11-15
  • 打赏
  • 举报
回复
上面说的都有些道理,我整理了下大家的意见。
1、id这个变量是一个共享资源,所谓“共享资源”,指的是多个线程可以同时访问的数据结构、文件等信息实体。
2、你这段程序可以分为2段来看,一段是运算,一段是输出。

3、你代码中开启了10个线程访问共享资源id,对他进行运算。当第8个线程运算后。
4、第6个和第7个线程运行到输出,但是此时id已经被第8个线程重新计算为9,所以第6个和第7个线程输出的结果是9。

代码做了下改动,应该有更好的方法。请参考
package com.test;

public class Task implements Runnable {
private static int id = 0;
private int threadID = 0;
public Task() {
}

public void run() {
synchronized(this){
threadID = id;
System.out.println("id=" + id++);
System.out.println("threadID=" + threadID);
}
}
}
功夫熊猫 2013-11-15
  • 打赏
  • 举报
回复
synchronized (this) {}
hack517 2013-09-26
  • 打赏
  • 举报
回复
楼上的都是正解。start()不是调用就能立即运行的(具体得看情况),有可能需要一段时间后才运行。你正好要到了延迟,才导致一系列疑问。
djdjsw 2013-09-17
  • 打赏
  • 举报
回复
ThreadID同步是一定的,因为其声明为private final int threadID=id++;不是共享的。而id声明为static,则其为共享的,调用输出时,其id也许已经被++了。
骑士的崛起 2013-09-16
  • 打赏
  • 举报
回复
创建N个Task有点怪,不知道你要达到什么目的,可以给你解释下你的代码为什么出现这个结果。

for(int i=0;i<10;i++){
   es.execute(new Task()); 
}
会产生10个实例,第一个实例d为0,threadID也为0,由于d为static,第二个实例d为1,threadID为1,以此类推10个实例。 线程池执行实例的start()方法和创建实例的先后没准,你这个是创建好4个实例后,才执行第一个实例的start方法,就会出现: threadID=0 id=5 线程池是同步的,所以10个线程执行没有先后,就会出现: threadID=8 id=10 threadID=4 第9个创建的实例执行start后,第5个创建的实例才执行start。 如有错误请纠正。
失落夏天 2013-09-16
  • 打赏
  • 举报
回复
static静态的是多个对象共享的。 因为是多线程,所以我觉得执行的顺序应该是 先new Task()若干个对象出来,这时候 private static int id=0; private final int threadID=id++; 就已经被赋值了,但是run方法还没有被执行,threadID各个对象之间不影响,但是id是共享的,所以会改变,最后输出值会一样。 然后这若干个对象在一起执行run方法输出。

67,513

社区成员

发帖
与我相关
我的任务
社区描述
J2EE只是Java企业应用。我们需要一个跨J2SE/WEB/EJB的微容器,保护我们的业务核心组件(中间件),以延续它的生命力,而不是依赖J2SE/J2EE版本。
社区管理员
  • Java EE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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