public class TestThread extends Thread{
private Integer ticketNum = 10;
public void run() {
synchronized (this) {//这个同步代码块和下面的while调换位置会有完全不同的结果
while(true) {
if(this.ticketNum > 0) {
try {
System.out.println(Thread.currentThread().getName()+":"+this.ticketNum);
this.ticketNum --;
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}else{
break;
}
}
}
}
public static void main(String[] args) {
TestThread t = new TestThread();
new Thread(t, "t1").start();
new Thread(t, "t2").start();
}
}
※推荐使用Runnable实现类,然后Thread thread=new Thread(Runnable实现类对象)的方法定义线程。
当我们定义多个线程的时候,虽然多线程对同一资源的访问与操作冲突问题解决了,但是会发现,每次输出的结果,都是同一个线程在执行,追根溯源的话,还是要说一下同步的原理。
以synchronized同步代码块为例:
同步是将多线程要共同操作的部分标记出来,并且制作一个信物,当多个线程执行到被标记为同步代码块的位置时,多个线程之间将会争夺信物。因为信物只有一个,获得信物的一个线程将得到权限执行同步代码块里的代码,当执行完代码块中的代码后,则会将信物交还给该同步代码块,然后下次运行到这里的时候,再与其他线程竞争, 看谁能拿到信物,继续循环往复。
以上为本人对于同步代码块的杜撰,但是根据以上的内容中,我们会发现,只有当一个线程执行完代码块中的代码后,才会将信物归还。也就是说,如果代码块中有for循环,则这个正在执行代码块的线程要执行到for循环结束后,才会将信物归还,因此会导致一开始所说的情况。所以在使用同步机制的时候,要分清循环结构所在的位置