package com.robingdo.test;
public class ThreadWithOutLockTest implements Runnable {
private int bit=100;
public void run() {
System.out.println("pre"+this.bit+":threadname:"+Thread.currentThread().getName());
bit--;
System.out.println("aft"+this.bit+":threadname:"+Thread.currentThread().getName());
}
public static void main(String s[]) {
ThreadWithOutLockTest test=new ThreadWithOutLockTest();
Thread thread1=new Thread(test,"thread1");
Thread thread2=new Thread(test,"thread2");
Thread thread3=new Thread(test,"thread3");
Thread thread4=new Thread(test,"thread4");
thread1.start();
thread2.start();
thread3.start();
thread4.start();
}
}
两次执行后,后台的打印结果是:
pre100:threadname:thread2
pre100:threadname:thread4
pre100:threadname:thread3
aft97:threadname:thread3
pre100:threadname:thread1
aft98:threadname:thread4
aft99:threadname:thread2
aft96:threadname:thread1
pre100:threadname:thread1
aft99:threadname:thread1
pre99:threadname:thread2
pre99:threadname:thread3
aft97:threadname:thread3
aft98:threadname:thread2
pre97:threadname:thread4
aft96:threadname:thread4
第二次的运行结果明显看出有问题,原因就在于多线程是并发运行的,4个线程几乎同一时间进入成员方法run(),然后对bit减一,执行system打印的时候也是并发的,所以四个线程打印出来的结果都可能是100,99,98,97,96其中任何一个,所以综上,多线程对于成员对象和成员方法的调用,如果不控制并发机制,那么几乎是乱套的,所以现在来看下怎么做才能使线程有序执行,其实乱套的根本原因就是4个线程并发进入成员方法run(),所以我们确保进入run()方法的线程只能有一个,而且必须在执行完了该方法,另外一个线程才能进入该方法,这就是多线程里面的锁的概念,现在对以上程序做下修改
package com.robingdo.test;
public class ThreadWithLockTest implements Runnable {
private int bit=100;
public void run() {
String lock="lock";
synchronized (lock) {
System.out.println("pre"+this.bit+":threadname:"+Thread.currentThread().getName());
bit--;
System.out.println("aft"+this.bit+":threadname:"+Thread.currentThread().getName());
}
}
public static void main(String s[]) {
ThreadWithLockTest test=new ThreadWithLockTest();
Thread thread1=new Thread(test,"thread1");
Thread thread2=new Thread(test,"thread2");
Thread thread3=new Thread(test,"thread3");
Thread thread4=new Thread(test,"thread4");
thread1.start();
thread2.start();
thread3.start();
thread4.start();
}
}
在run方法加入锁对象,把方法体用同步块上锁,这样进入方法的线程只有一个,并且其他线程只能在释放资源后才能获得资源,执行两次程序,打印出来的结果是
pre100:threadname:thread1
aft99:threadname:thread1
pre99:threadname:thread4
aft98:threadname:thread4
pre98:threadname:thread3
aft97:threadname:thread3
pre97:threadname:thread2
aft96:threadname:thread2
pre100:threadname:thread1aft99:threadname:thread1pre99:threadname:thread4aft98:threadname:thread4pre98:threadname:thread3aft97:threadname:thread3pre97:threadname:thread2aft96:threadname:thread2这样打印结果就正常了