首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > JAVA > J2SE开发 >

问一个关于线程的有关问题,一直不是弄的很清楚

2012-02-22 
问一个关于线程的问题,一直不是弄的很清楚!packagecom.pos.testpublicclassSimpleThreadextendsThread{pu

问一个关于线程的问题,一直不是弄的很清楚!
package   com.pos.test;

public   class   SimpleThread   extends   Thread   {
public   int   countDown   =   5;
private   static   int   threadCount   =   0;
private   int   threadNumber   =   ++threadCount;
public   SimpleThread(){
System.out.println( "making   "+threadNumber);
}

public   void   run(){
while(true){
System.out.println( "thread "+threadNumber+ "( "+countDown+ ") ");
if(--countDown==0)   return;
}
}
/**
  *   @param   args
  */
public   static   void   main(String[]   args)   {
for(int   i   =0;i <5;i++)
new   SimpleThread().start();
System.out.println( "end ");

}

}
这是thinkinjava的原程序,运行是正常的,下面是我改的程序,问什么就发生了并发的问题,刚开始学习线程,对同一个类实例化的线程对象是否共享一块内存,是否每个对象中的变量相互独立弄的不是很清楚,希望有知道的能给我一点帮助!

public   class   SimpleThread   implements   Runnable   {
public   int   countDown   =   5;
private   static   int   threadCount   =   0;
private   int   threadNumber   =   ++threadCount;
public   SimpleThread(){
System.out.println( "making   "+threadNumber);
}

public   void   run(){
while(true){
System.out.println( "thread "+threadNumber+ "( "+countDown+ ") ");
if(--countDown==0)   return;
}
}
/**
  *   @param   args
  */
public   static   void   main(String[]   args)   {
SimpleThread   st   =   new   SimpleThread();
for(int   i   =0;i <5;i++)

new   Thread(st).start();
System.out.println( "end ");

}

}


[解决办法]
把你第二个程序改了一下:
package com.whj.jdk.lang;

public class SimpleThread extends Thread {
private static int threadCount = 0;

/**
* @param args
*/
public static void main(String[] args) {

SimpleThread st = new SimpleThread(); // Error Code
for (int i = 0; i < 5; i++) {
// new SimpleThread().start();
new Thread(st).start(); // Error Code
}
System.out.println( "end ");

}

public int countDown = 5;

private final int threadNumber = ++threadCount;

public SimpleThread() {
System.out.println( "making " + threadNumber);
}

@Override
public void run() {
while (true) {
System.out.println( "thread " + threadNumber + "( " + countDown + ") ");
if (--countDown == 0) {
System.out.println( "GO ");
return;
}
}
}

}

运行后的输出结果是:
making 1
end
thread1(5)
thread1(4)
thread1(3)
thread1(2)
thread1(1)
GO
thread1(0)
thread1(-1)
thread1(-2)
thread1(-3)
thread1(-4)
thread1(-5)
thread1(-6)
thread1(-7)
thread1(-8)
thread1(-9)
thread1(-10)
thread1(-11)
thread1(-12)
thread1(-13)
thread1(-14)

以下被我中断。

你仔细分析一下就知道为什么了。
[解决办法]


您的第一个程序的运行结果是:
making 1
making 2
making 3
making 4
making 5
end
thread2(5)
thread4(5)
thread1(5)
thread4(4)
thread2(4)
thread1(4)
thread4(3)
thread2(3)
thread1(3)
thread3(5)
thread4(2)
thread5(5)
thread2(2)
thread1(2)
thread3(4)
thread4(1)
thread5(4)
thread2(1)
thread1(1)
thread3(3)
thread5(3)
thread3(2)
thread5(2)
thread3(1)
thread5(1)

从这结果我们可以看出来,这个测试程序创建了5个线程,并且这5个线程是相互独立的,即它们对各自countDown 变量进行操作(每次减1,一共执行5次),所以5个线程一共执行25次,对应上面的结果的25行。他们并不是对countDown 进行并发访问,此时countDown 不是共享的资源

而你的第二个程序明显有错误,既然SimpleThread 是实现了Runnable接口,并且在测试的代码中用同一SimpleThread 的对象创建了5个线程,所以这5个线程共享了资源countDown ,即它们对countDown 一同进行操作,所以一定要提供对变量countDown 的并发操作。

这是我修改了你的代码
package threadTest;

public class SimpleThread implements Runnable {

private int countDown = 25;
//private static int threadCount = 0;
//private int threadNumber = ++threadCount;
String str= new String( " ");

public void run(){
while(true){
synchronized(str){
if(countDown > 0){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " :( " + countDown-- + ") " );
//System.out.println( "thread " + threadNumber + "( " + --countDown + ") ");
}
}
}
}
/**
* @param args
*/
public static void main(String[] args) {
SimpleThread st = new SimpleThread();
for(int i =0;i <5;i++)
new Thread(st).start();
}

}

在上面我注释了你有毛病的地方。你只创建了一个SimpleThread实例,且threadCount是静态的变量,所以threadNumber一直是1,输出的结果永远是thread1,尽管你创建了5个线程。


这是我的测试结果,我把countDown 设为25,以便更好的观察结果

Thread-1 :(25)
Thread-0 :(24)
Thread-2 :(23)
Thread-3 :(22)
Thread-4 :(21)
Thread-1 :(20)
Thread-0 :(19)
Thread-2 :(18)
Thread-3 :(17)
Thread-4 :(16)
Thread-1 :(15)
Thread-0 :(14)
Thread-2 :(13)
Thread-3 :(12)
Thread-4 :(11)
Thread-1 :(10)
Thread-0 :(9)
Thread-2 :(8)
Thread-3 :(7)
Thread-4 :(6)
Thread-1 :(5)
Thread-0 :(4)
Thread-2 :(3)
Thread-3 :(2)
Thread-4 :(1)

从上面可以看出5个线程对变量countDown 进行了并发访问,5个线程一共进行了25次操作


热点排行