java线程-线程的同步-同步的方法
在电商的实际开发中遇到了这样一种情况,在管理员与用户同时操作一条订单数据的时候,好比用户正在取消订单,而管理员在发货。这样就会导致这条订单的数据出现问题。所以想来研究一下线程锁用来解决这个问题。贴上实例
public class synchronizedTest {
private int i = 0;
public static void main(String [] args){
synchronizedTest test = new synchronizedTest();
test.startThread();
}
// 启动线程的方法
private void startThread(){
for (int j = 0; j < 10; j++) {
new Thread(new ThreadWorked()).start();
}
}
// 内部线程类
class ThreadWorked implements Runnable{
public void run(){
showMessage();
}
}
// 没有同步的方法
private void showMessage(){
Thread currentThread = Thread.currentThread();
System.out.println("当前线程为:" +currentThread.getName()+"-----输出值:"+i);
++i;
}
}
输出的值:
当前线程为:Thread-0-----输出值:0
当前线程为:Thread-2-----输出值:0
当前线程为:Thread-1-----输出值:0
当前线程为:Thread-3-----输出值:2
当前线程为:Thread-4-----输出值:4
当前线程为:Thread-5-----输出值:5
当前线程为:Thread-6-----输出值:6
当前线程为:Thread-7-----输出值:7
当前线程为:Thread-8-----输出值:8
当前线程为:Thread-9-----输出值:9
可以很明显的看见,在线程处理完成后没有使用同步的输出的值出现了重复。导致实际数据不同
上面的结果是错误的,导致错误的原因是多个线程并发访问了竞争资源i,并对i的属性做了改动。
可见同步的重要性。
修改 showMessage()
<pre name="code" class="java" style="color: rgb(85, 85, 85); font-size: 14px; line-height: 28px;"> // 加上同步关键字的方法
private synchronized void showMessage(){
Thread currentThread = Thread.currentThread();
System.out.println("当前线程为:" +currentThread.getName()+"-----输出值:"+i);
++i;
}
输出的值:
当前线程为:Thread-0-----输出值:0
当前线程为:Thread-1-----输出值:1
当前线程为:Thread-2-----输出值:2
当前线程为:Thread-3-----输出值:3
当前线程为:Thread-4-----输出值:4
当前线程为:Thread-5-----输出值:5
当前线程为:Thread-8-----输出值:6
当前线程为:Thread-6-----输出值:7
当前线程为:Thread-9-----输出值:8
当前线程为:Thread-7-----输出值:9
注意:
通过前文可知,线程退出同步方法时将释放掉方法所属对象的锁,但还应该注意的是,同步方法中还可以使用特定的方法对线程进行调度。这些方法来自于java.lang.Object类。
void
notify()
唤醒在此对象监视器上等待的单个线程。
void notifyAll()
唤醒在此对象监视器上等待的所有线程。
void wait()
导致当前的线程等待,直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法。
void wait( long timeout)
导致当前的线程等待,直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法,或者超过指定的时间量。
void wait( long timeout, int nanos)
导致当前的线程等待,直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法,或者其他某个线程中断当前线程,或者已超过某个实际时间量。
结合以上方法,处理多线程同步与互斥问题非常重要.