先来看一个例子:
public class Test2
{
public synchronized static void info(String info){
try
{
//Thread.sleep(100);
}catch(Exception e)
{
e.printStackTrace();
}
System.out.println(info);
}
public void excute() throws InterruptedException{
new Thread(new Excutor(),"T1").start();
new Thread(new Excutor(),"T2").start();
new Thread(new Excutor(),"T3").start();
new Thread(new Excutor(),"T4").start();
}
/**
* @param args
*/
public static void main(String[] args)
{
try
{
new Test2().excute();
}catch(InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
class Excutor extends Thread{
@Override
public void run()
{
System.out.println("T:"+Thread.currentThread().getName());
info("INFO:"+Thread.currentThread().getName());
}
}
}
执行结果:
T:T2
T:T3
T:T1
T:T4
也有可能是其他的顺序。
在上面的例子中,在main函数中连续创建了4个线程,并以此启动,但是,其执行结果却不是按照线程的创建顺序来启动的。所以不要指望通过线程的创建、启动
顺序来控制其执行顺序。
至于为什么是这样的结果,以后在讨论。
synchronized 关键字的效果:
将上面例子中的类Excutor修改为:
class Excutor extends Thread{
@Override
public void run()
{
System.out.println("T:"+Thread.currentThread().getName());
info("INFO:"+Thread.currentThread().getName());//新增加
}
}
执行结果:
T:T1
T:T3
T:T2
INFO:T3
INFO:T2
T:T4
INFO:T4
INFO:T1
由上可见:加了这个关键字的函数或代码块,只能保证其在一个线程中不会被其他线程抢占,而不能保证调用该函数或代码块的顺序。