线程为何要使用同步?
java允许多线程并发控制,当多个线程同时操作一个可共享的资源变量时(如数据的增删改查), 将会导致数据不准确,相互之间产生冲突,因此加入同步锁以避免在该线程没有完成操作之前,被其他线程的调用, 从而保证了该变量的唯一性和准确性。
volatile只能解决多线程可见,不能解决线程安全问题。
Volatile关键字的作用是全局变量在多个线程之间可见。
Thread的几个重要方法
a、start()方法,调用该方法开始执行该线程;
b、stop()方法,调用该方法强制结束该线程执行;
c、join方法,调用该方法等待该线程结束。
d、sleep()方法,调用该方法该线程进入等待。
e、run()方法,调用该方法直接执行线程的run()方法,但是线程调用start()方法时也会运行run()方法,区别就是一个是由线程调度运行run()方法,一个是直接调用了线程中的run()方法!!
注意,wait()与notify()方法是Object的方法,不是Thread的方法!!同时,wait()与notify()会配合使用,分别表示线程挂起和线程恢复。
wait()与sleep()的区别
wait()会释放对象锁,释放cpu
sleep()不会释放对象锁,释放cpu。
线程使用同步的前提条件
1)必须要有两个或者两个以上的线程。
2)必须是多线程使用同一个锁。
3)必须保证只有一个线程在运行。
线程同步运行原理
1)有一个线程已经拿到了锁,其他线程已经有cpu执行的,一直在排队,等待其他线程释放锁。
2)锁是什么时候释放呢?代码执行完毕或者程序抛出异常都会释放锁。
3)锁释放后,其他线程开始获取锁进入同步代码。
关于线程同步简单说明:
1)在普通方法上面加上synchronized 即为同步函数
2)同步函数使用的this锁 (synchronized (this)==public synchronized void save(){})
3)静态同步函数不使用this锁
4)同步代码块 :有synchronized关键字修饰的语句块 (synchronized(object){ })。
关于Lock对象和synchronized关键字的选择:
a.最好两个都不用,使用一种java.util.concurrent包提供的机制, 能够帮助用户处理所有与锁相关的代码。
b.如果synchronized关键字能满足用户的需求,就用synchronized,因为它能简化代码
c.如果需要更高级的功能,就用ReentrantLock类,此时要注意及时释放锁,否则会出现死锁,通常在finally代码释放锁
两个线程,一个线程使用同步函数,另一个线程使用静态同步函数能实现同步吗?
不能,同步函数使用的this锁,静态同步函数使用的当前字节码文件(xx.class)。
线程如何实现同步?
1)synchronized 自动加锁
class Bank {
private int account = 100;
public int getAccount() { return account; }
public synchronized void save(int money) {
account += money;
}}
2)lock 手动加锁
ReentrantLock() : 创建一个ReentrantLock实例 lock() : 获得锁 unlock() : 释放锁
例如:
class Bank {
private int account = 100;
private Lock lock = new ReentrantLock(); //需要声明这个锁
public int getAccount() {
return account;
}
public void save(int money) {
lock.lock();
try{
account += money;
}finally{
lock.unlock();
} } }
网友评论