java 线程同步

线程同步

一.使用synchronized关键字
由于每个java对象都有一个内置锁,用synchronized修饰方法或者代码块时,内置锁会保护整个方法或代码块,要想执行这个方法或者代码块必须获得其内置锁,运行时会加上内置锁,当运行结束时,内置锁会打开。由于同步是一种高开销的工作,所以尽量减少同步的内容,只需同步代码块就可以。(ps:synchronized是不能锁住不同对象的线程的,只能锁住同一个对象的线程,也就是说锁住的是方法所属的主体对象自身)

1.修饰方法

public class Sy_Thread_Demo1 implements Runnable {
    static int num = 10000;
    //修饰方法加同步锁synchronized
    @Override
    public synchronized void run() {
        while(true){
            if(num>=0){
                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName()+"正在运行第"+num--+"次线程!");
            }else{
                break;
            }
        }
    }
}
public class Sy_Test {
    public static void main(String[] args) {
        Sy_Thread_Demo1 st = new Sy_Thread_Demo1();
        Thread t1 = new Thread(st);
        t1.setName("线程1");
        Thread t2 = new Thread(st);
        t2.setName("线程2");
        t1.start();
        t2.start();
    }
}

2.修饰代码块

public class Sy_Thread_Demo2 implements Runnable{
    static int num = 10000;
    @Override
    public void run() {
        synchronized (this){
            while(true){
                if(num>=0){
                    try {
                        Thread.sleep(10);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName()+"正在运行第"+num--+"次线程!");
                }else{
                    break;
                }
            }
        }
    }
}
public class Sy_Test2 {
    public static void main(String[] args) {
        Sy_Thread_Demo2 st = new Sy_Thread_Demo2();
        Thread t1 = new Thread(st);
        t1.setName("线程1");
        Thread t2= new Thread(st);
        t2.setName("线程2");
        t1.start();
        t2.start();
    }
}

二.wait与notify

  • wait(),使一个线程处于等待状态,并释放所持对象的锁,与sleep不同,sleep不会释放对象锁。
  • notify(),唤醒一个处于阻塞状态的线程,进入就绪态,并加锁,只能唤醒一个线程,但不能确切知道唤醒哪一个,由JVM决定,不是按优先级。其实不是对对象锁的唤醒,是告诉调用wait方法的线程可以去竞争对象锁了。wait和notify必须在synchronized代码块中调用。
  • notifyAll(),唤醒所有处于阻塞状态的线程,并不是给他们加锁,而是让他们处于竞争。
    为什么wait和notify要在synchronized代码块中使用
    调用wait()就是释放锁,释放锁的前提是必须要先获得锁,先获得锁才能释放锁,释放锁后进入等待队列。
    notify(),notifyAll()是将锁交给含有wait()方法的线程,让其继续执行下去,如果自身没有锁,怎么叫把锁交给其他线程呢;(本质是让处于阻塞队列的线程进入等待队列竞争锁)
  • 5
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值