JAVA多线程安全之wait(),notify(),sleep(),synchronized(),lock(),BLOCKED状态
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLiAzNfRHLGZkRGZkRfJ3bs92YsYTMfVmepNHL9M2Ra1mVyoFbk1mWr50MMBjVtJWd0ckW65UbM5WOHJWa5kHT20ESjBjUIF2X0hXZ0xCMx81dvRWYoNHLrdEZwZ1Rh5WNXp1bwNjW1ZUba9VZwlHdssmch1mclRXY39CXldWYtlWPzNXZj9mcw1ycz9WL49zZuBnL2kDOzMTN1YTM1EDNwEjMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
sleep()
sleep()中指定的时间是线程不会运行的最短时间。因此,sleep()方法不能保证该线程睡眠到期后就 开始立刻执行。
BLOCKED(锁阻塞)
Waiting(无限等待)
某个对象的 Object.wait 方法的线程会等待另一个线程调用此对象的 Object.notify()方法 或 Object.notifyAll()方法。
简单来讲,并发读写操作导致线程不安全(数据被使用两次,不存在的数据等等)
示例
//wait和notify必须使用同一个锁对象
public class DemoWaitAndNotify {
public static void main(String[] args) {
Object obj = new Object();
new Thread(){
@Override
public void run() {
while(true){
synchronized (obj){
System.out.println("请等待5s");
try {
obj.wait();//wait也可以加时间
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("好了");
}
}}
}.start();
new Thread(){
@Override
public void run() {
while (true){
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (obj){
System.out.println("吃吧乖");
obj.notify();//如果多个等待线程,随机唤醒一个
//obj.notify();//全部唤醒
}
}
}
}.start();
}
}
synchronized()
/*
* 只用共享资源的读写访问才需要同步化,如果不是共享资源,那么根本没有同步的必要。
*
*1. c3线程获得cpu资源,执行 1操作,在c3想同步count值1到主内存中去时。
* 2. c2线程得到了cpu的资源,也同样执行 1操作 但没 1前count的值是0,而不是1,c2执行完后,打印count=1的值,并且把数据同步到主内存中。
* 3. 此时c3又得到了cpu的资源,于所执行刚才没有完成的同步操作,同时又打印count=1的值。
*
* */
public class ThreadSafe implements Runnable{
//synchronized和synchronized静态方法
private int ticket=100;
Object obj=new Object();
@Override
public void run() {
while (true){
synchronized (obj){//关键字
if(ticket>0){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"正在卖"+ticket+"张票");
ticket--;
}
}
}
}
}
静态synchronized
//静态方法
public class DemoSafe02 implements Runnable{
private static int ticket=100;
//Object obj=new Object();
@Override
public void run() {
while (true){
// synchronized (obj){//guan键字
payTicket();
}
}
public static synchronized void payTicket(){
if(ticket>0){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"正在卖"+ticket+"张票");
ticket--;
}
}
}
Lock()
public class DemoSafe03 implements Runnable{
//lock方法
private int ticket=100;
Lock l1=new ReentrantLock();
@Override
public void run() {
while (true){
l1.lock();//关键字
if(ticket>0){
try {
Thread.sleep(100);
System.out.println(Thread.currentThread().getName()+"正在卖"+ticket+"张票");
ticket--;
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
l1.unlock();//无论程序是否异常,都会把锁释放
}
}
}
}
}