技术开发 频道

JAVA线程:两种不同创建方式全面解析

  学习线程也是一种摆脱传统编程思维的奇妙之旅,这也是我想好好复习线程的重要原因之一,对线程的学习完全可以当做一门新语言来进行,而且各种不同语言实现线程的差异度都不大,这也是跳出语言框框的一次重要实践。

  让我们回归到程序里吧,上面的例子里我们不断执行程序会发现:每次运行的结果都不一样,名称不同的线程会交替运行,这到底是什么原因造成的呢?产生的原因是java虚拟机里线程的调度机制,到底哪个线程先执行那个线程后执行,线程调度是使用一个非常随机的方式进行管理的,导致结果输出的混乱。解决这个问题的方法就是使用Thread所带的join()方法,大家请看下面的代码:

package cn.com.sxia;public class SimpleThread extends Thread {
    
private int countDown = 5;//构建的Thread对象内部使用的数据
    private static int threadCount = 0;//静态变量属于类,目的是为了每个构建的线程定义一个名称
        public SimpleThread(){
        
super("" + ++threadCount);
        start();
    }
        
public String toString(){
        
return "#" + getName() + ": " + countDown;
    }
        
public void run(){
        
while(true){
            System.out.println(
this);
            
if (--countDown == 0)
                
return;
        }
    }
        
public static void main(String[] args) throws InterruptedException {
                
for (int i = 0;i < 5;i++)
        {
            
new SimpleThread().join();
        }
    }
}

  结果如下:

#1: 5
#
1: 4
#
1: 3
#
1: 2
#
1: 1
#
2: 5
#
2: 4
#
2: 3
#
2: 2
#
2: 1
#
3: 5
#
3: 4
#
3: 3
#
3: 2
#
3: 1
#
4: 5
#
4: 4
#
4: 3
#
4: 2
#
4: 1
#
5: 5
#
5: 4
#
5: 3
#
5: 2
#
5: 1

   大家看到了输出的结果是按线程构建的顺序进行的,这个现象说明了join()方法可以改变java里线程随机调度的现象,join方法会让使用join方法的线程处于等待的状态,只有当正在执行线程结束运行后后才会调用使用到join方法的线程。

  前面讲到了,线程对象要被销毁要满足两个条件:一个是该线程对象没有被引用,一个是run方法停止运行了。但是当线程跳出了run方法,java虚拟机不一定知道线程已经执行完毕,这个需要一个过程,因此java中有了个yield方法,这个方法告诉java虚拟机,线程的任务已经完成了,可以释放该线程的CPU留给其他线程使用了,下面是使用yield方法的例子:

package cn.com.sxia;public class YieldingThread extends Thread{
    
private int countDown = 5;
    
private static int threadCount = 0;
        
public YieldingThread()
    {
        
super("" + ++threadCount);
        start();
    }
        
public String toString(){        return "#" + getName() + ": " + countDown;
    }
        
public void run()
    {
        
while(true)
        {
            System.out.println(
this);
            
if (--countDown == 0)
                
return;
            yield();
        }
    }
        
public static void main(String[] args)
    {
        
for (int i = 0;i < 5;i++)
        {
            
new YieldingThread();
        }
    }
}
0
相关文章