栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

对象及变量的并发访问(二)——synchronized同步语句块(3)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

对象及变量的并发访问(二)——synchronized同步语句块(3)

目录
  • 11.将任意对象作为对象监视器
  • 12.多线程的死锁
  • 13.锁对象的改变

接上一篇文章——【对象及变量的并发访问(二)——synchronized同步语句块(2)】
网址为:https://blog.csdn.net/qq_44307209/article/details/125420587

11.将任意对象作为对象监视器

  同步方法容易造成死循环。这时就可以使用同步块来解决这样的问题。
创建项目twoStop,类Service.java的代码如下:

public class Service {

    Object objectA = new Object();
    public void methodA() {
        synchronized (objectA) {
            System.out.println(" methodA begin");
            boolean isContinueRun = true;
            while (isContinueRun) {
            }
            System.out.println(" methodA end");
        }
    }
    Object objectB = new Object();
    public void methodB() {
        synchronized (objectB) {
            System.out.println(" methodB begin");
            System.out.println(" methodB end");
        }
    }

}

创建线程类ThreadA.java代码如下:

public class ThreadA extends Thread {

    private Service service;

    public ThreadA(Service service) {
        super();
        this.service = service;
    }

    @Override
    public void run() {
        super.run();
        service.methodA();
    }
}

创建线程类ThreadB.java代码如下:

public class ThreadB extends Thread {

    private Service service;

    public ThreadB(Service service) {
        super();
        this.service = service;
    }

    @Override
    public void run() {
        super.run();
        service.methodB();
    }
}

创建运行类Run.java代码如下:

public class Run {

    public static void main(String[] args) {
        Service service = new Service();
        ThreadA athread = new ThreadA(service);
        athread.start();
        ThreadB bthread = new ThreadB(service);
        bthread.start();
    }
}

运行结果如下所示:

 methodA begin
 methodB begin
 methodB end

没有出现同步等待的情况

12.多线程的死锁

  Java线程死锁是一个经典的多线程问题,因为不同的线程都在等待根本不可能被释放的锁,从而导致所有的任务都无法继续完成。在多线程技术中,“死锁”是必须避免的,因为这会造成线程的“假死”。
创建名称dealLockTest的项目,DealThread.java类代码如下:

public class DealThread implements Runnable {
    public String username;
    public Object lock1 = new Object();
    public Object lock2 = new Object();

    public void setFlag(String username) {
        this.username = username;
    }

    @Override
    public void run() {
        if (username.equals("a")) {
            synchronized (lock1) {
                try {
                    System.out.println("username = " + username);
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                synchronized (lock2) {
                    System.out.println("按lock1->lock2代码顺序执行了");
                }
            }
        }
        if (username.equals("b")) {
            synchronized (lock2) {
                try {
                    System.out.println("username = " + username);
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                synchronized (lock1) {
                    System.out.println("按lock2->lock1代码顺序执行了");
                }
            }
        }
    }
}

创建运行类Run.java代码如下:

public class Run {
    public static void main(String[] args) {
        try {
            DealThread t1 = new DealThread();
            t1.setFlag("a");
            Thread thread1 = new Thread(t1);
            thread1.start();
            Thread.sleep(100);
            t1.setFlag("b");
            Thread thread2 = new Thread(t1);
            thread2.start();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

运行结果如下所示:

username = a
username = b

出现死锁

  可以使用JDK自带的工具来监测是否有死锁的现象。首先进入CMD 工具,再进入JDK的安装文件夹中的bin目录,执行jps命令。得到运行线程Run的id值是20552,再执行jstack命令(命令:jstack -l 20552),查看结果。

  死锁是程序设计的Bug,在设计程序时就要避免双方互相持有对方的锁的情况。需要说明的是,本实验使用synchronized嵌套的代码结构来实现死锁,其实不使用嵌套的synchronized 代码结构也会出现死锁,与嵌套不嵌套无任何的关系,不要被代码结构所误导。只要互相等待对方释放锁就有可能出现死锁。

13.锁对象的改变

  在将任何数据类型作为同步锁时,需要注意的是,是否有多个线程同时持有锁对象,如果同时持有相同的锁对象,
则这些线程之间就是同步的;如果分别获得锁对象,这些线程直接就是异步的。


以上代码下载请点击该链接:https://github.com/Yarrow052/Java-package.git

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/988708.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号