Java多线程—线程同步(单信号量互斥)

博客 动态
0 183
优雅殿下
优雅殿下 2022-05-03 10:58:44
悬赏:0 积分 收藏

Java多线程—线程同步(单信号量互斥)

JDK中Thread.State类的几种状态

线程的生命周期


?
?
?
?

线程的安全问题(同步与互斥)



方法一:同步代码块

多个线程的同步监视器(锁)必须的是同一把,任何一个类的对象都可以

      synchronized(同步监视器){            }  //说明:操作共享数据的代码,即为需要被同步的代码(对共享数据的操作)

对于Thread实现和Runnable实现,同步锁需要区别

1.Thread下的同同步锁

class WinThread extends Thread{/*    方式一 继承Thread*/    private static int ticket=100;  //需要设置静态变量    private static Object ticketLock=new Object(); //同步监视器,静态,因为要是共享唯一变量    @Override    public void run() {        while(true)        {            synchronized (ticketLock){                if (ticket > 0)                {                    System.out.println(this.getName() + "卖票: " + ticket);                    ticket--;                }                else break;            }        }    }}

2.Runnable下的同步锁

class winRunnable implements Runnable{    private int ticket=100; //不用设置成静态变量    private Object obj=new Object();    //声明一个对象为锁    @Override    public void run() {        while(true)        {            try {                sleep(100);            } catch (InterruptedException e) {                e.printStackTrace();            }            synchronized(obj){  //互斥操作                if (ticket > 0)                {                    System.out.println(Thread.currentThread().getName() + "卖票: " + ticket);                    ticket--;                }                else break;            }        }    }}

Thread下可以考虑用WinThread.class当锁,而Runnable下可以考虑用this当锁(总之要分析是不是同一个锁)
自己的坑:不能把共享的数据当作锁(例如WinThread下的int ticket改成Integer后当锁),这里还是会有问题


方法二:同步方法(代码略)

多声明一个对共享数据数据操作的方法,在方法的前面添加声明synchronized,而不是直接在run()前面加
1.同步方法中也涉及到同步锁,但锁是默认的
2.非静态的同步方法,锁是this
静态的同步方法,锁是当前类本身——xxx.class

 *              同步方法synchronized实现runnable接口 *              private synchronized void 方法(){//普通同步方法的同步监视器是this *              //需要互斥的代码 *          }
 *              同步方法synchronized实现继承Thread类 *                  因为不同线程是Thread类的不同对象,所以一般要用静态 *              private static synchronized void 方法(){//静态同步方法默认同步监视器是类本身 *                  //需要互斥的代码 *              }

同步的局限性:操作同步代码时,只能有一个线程参与,其他线程等待,相当于互斥量为1

单例模式的同步问题



死锁问题



方法二:Lock(锁) ---JDK5.0新增

class LockRunnable implements Runnable{    private int ticket=100; //不用设置成静态变量    private ReentrantLock lock=new ReentrantLock(true); //true为选择FIFO的公平    @Override    public void run() {        while(true)        {            try {                try {                    sleep(100);                } catch (InterruptedException e) {                    e.printStackTrace();                }                lock.lock();                if (ticket > 0)                {                    System.out.println(Thread.currentThread().getName() + "卖票: " + ticket);                    ticket--;                }                else break;            }finally {                lock.unlock();            }        }    }}

面试题:synchronized 与 Lock 的区别
相同:二者都可以解决线程安全问题
不同:synchronized机制在执行完相应的同步代码之后,自动的释放同步监视器
Lock需要手动的启动同步 .lock() ,同时结束同步也需要手动 .unlock()

posted @ 2022-05-03 10:10 JayerListen 阅读(0) 评论(0) 编辑 收藏 举报
回帖
    优雅殿下

    优雅殿下 (王者 段位)

    2018 积分 (2)粉丝 (47)源码

    小小码农,大大世界

     

    温馨提示

    亦奇源码

    最新会员