精华内容
下载资源
问答
  • java线程中使用“私有最终对象”锁定有什么用?据我所知,我认为使类成为线程安全的,我们应该使用内部锁定,我们将所有方法标记synchronized& amp;使用“this”将它们锁定在Object的监视器上?或者我们...

    java多线程中使用“私有最终对象”锁定有什么用?

    据我所知,我认为要使类成为线程安全的,我们应该使用内部锁定,我们将所有方法标记为synchronized& amp;使用“this”将它们锁定在Object的监视器上?或者我们可以用方法中的私有最终Object锁替换在类的“this”上标记为synchronized的方法,以锁定通用Object锁以使其线程安全吗?

    仅举例来说使用内部锁定的代码:

    public class Counter{

    // Locks on the object's monitor

    public synchronized void changeValue() {

    // ...

    }

    }

    我们可以使用以下外部锁替换上面的代码:

    public class Counter{

    private final Object lock = new Object(); // private final lock object

    public void changeValue() {

    synchronized (lock) { // Locks on the private Object

    // ...

    }

    }

    }

    是否建议使用上述外部锁而不是使用内部锁定来使类成为线程安全的?如果我的理解不对,请纠正我?

    展开全文
  • 然后为什么要有静态?简而言之,一个非静态方法获取静态通常是为了在防止静态数据上发生竞态条件。因为静态方法是属于类的,即对于静态方法而言是没有对象引用的概念的,那么此时就无法使用对象来对静态方法进行...

    首先什么是类锁?

    就像可以对类的每一个实例(对象)获取一个对象锁一样,对于每一个类都可以获取一个锁,我们称之为类锁。

    然后为什么要有静态锁?

    简而言之,一个非静态方法获取静态锁通常是为了在防止静态数据上发生竞态条件。因为静态方法是属于类的,即对于静态方法而言是没有对象引用的概念的,那么此时就无法使用对象来对静态方法进行锁定了。我们可以做这样的考虑,就是既然静态方法是属于类的,那么我们是否可以使用类对象来做锁定依据呢?答案是肯定的,我们可以使用表示当前类的类对象或者从属于当前类静态域的静态对象来做锁的判断依据。

    使用方法

    一个简单的例子,对比使用了静态锁和没使用了静态锁的两种情况

    package com.wly.javathread.chap3;

    /**

    * 测试静态锁(类锁)的使用

    * 静态锁(类锁)主要用来防止在静态数据上发生竞态条件,理论依据是要操作静态数据必须先获取到静态锁(类锁)的原理

    * @author wly

    *

    */

    public class TestStaticLock {

    static Score2 score2;

    static Score1 score1;

    /**

    * @param args

    */

    public static void main(String[] args) {

    //测试没有加静态锁的情况

    System.out.println("--测试没有加静态锁的情况--");

    Thread[] threads = new Thread[1000];

    for(int j=0;j<10;j++) { //循环测试多次

    score1 = new Score1();

    for(int i=0;i

    threads[i] = new Thread() {

    @Override

    public void run() {

    super.run();

    score1.add(10);

    try {

    this.sleep(3);

    } catch (InterruptedException e) {

    e.printStackTrace();

    }

    score1.deduct(10);

    }

    };

    threads[i].start();

    }

    //等待所有线程都结束

    for(int i=0;i

    try {

    threads[i].join();

    } catch (InterruptedException e) {

    e.printStackTrace();

    }

    }

    score1.printScore();

    }

    //测试加了静态锁的情况

    System.out.println("--测试加了静态锁的情况--");

    for(int j=0;j<10;j++) { //循环测试多次

    score2 = new Score2();

    for(int i=0;i

    threads[i] = new Thread() {

    @Override

    public void run() {

    super.run();

    score2.add(10);

    try {

    this.sleep(3);

    } catch (InterruptedException e) {

    e.printStackTrace();

    }

    score2.deduct(10);

    }

    };

    threads[i].start();

    }

    //等待所有线程都结束

    for(int i=0;i

    try {

    threads[i].join();

    } catch (InterruptedException e) {

    e.printStackTrace();

    }

    }

    score2.printScore();

    }

    }

    }

    /**

    * 没有加静态锁的实现

    * @author wly

    *

    */

    class Score1 {

    static int score;

    public void add(int num) {

    score += num;

    }

    public void deduct(int num) {

    score -= num;

    }

    public void printScore() {

    System.out.println("score:" + score);

    }

    }

    /**

    * 加了静态锁的实现

    * @author wly

    *

    */

    class Score2 {

    static int score;

    public void add(int num) {

    synchronized (Score2.class) {

    score += num;

    }

    }

    public void deduct(int num) {

    synchronized (Score2.class) {

    score -= num;

    }

    }

    public void printScore() {

    System.out.println("score:" + score);

    }

    }

    运行结果:

    --测试没有加静态锁的情况--

    score:10

    score:10

    score:10

    score:10

    score:20

    score:10

    score:10

    score:10

    score:10

    score:10

    --测试加了静态锁的情况--

    score:0

    score:0

    score:0

    score:0

    score:0

    score:0

    score:0

    score:0

    score:0

    score:0

    类锁和对象锁

    类锁和对象锁是两种不同的锁,如果一个非静态同步方法调用了一个静态同步方法,它就拥有了两个不同的锁。因为一个静态同步方法在没有对象引用的情况下不调用能非静态同步方法,所以这两种同步方法发生死锁的概率很小。

    其他锁定方式

    a.使用其他静态对象做锁定依据

    public class Test {

    private static int count = 0;

    private static final Object countLock = new Object();

    public void incrementCount() {

    synchronized (countLock) {

    count++;

    }

    }

    }

    b.在静态方法上使用synchronized修饰符

    public class Test {

    private static int count = 0;

    public static synchronized void incrementCount() {

    count++;

    }

    }

    O啦~~~

    谢谢!!

    展开全文
  • 为什么要使用这个词?在阅读有关Java线程的文章时,我经常注意到这样的表达:“当前线程是该对象的监视器的所有者”。 我的意思是:线程有权在对象上进行操作。 但是我很困惑,为什么我们使用“对象的监视器”而...

    多线程-Java中的对象监视器是什么意思? 为什么要使用这个词?

    在阅读有关Java线程的文章时,我经常注意到这样的表达:“当前线程是该对象的监视器的所有者”。 我的意思是:线程有权在对象上进行操作。 但是我很困惑,为什么我们使用“对象的监视器”而不是“对象的锁”?

    简而言之,我不知道“监控”一词的含义这个问题可能很奇怪而且很简单。 但我希望任何人都能帮助解决它。3KS

    6个解决方案

    44 votes

    但是我很困惑,为什么要使用“对象的监视器”一词而不是“对象的锁”?

    请参阅ulmangt的答案以获取在此上下文中解释“监视”一词的链接。

    为什么使用术语“监视”而不是“锁定”? 严格来说,这些术语的含义确实有所不同……尤其是如果您以最初打算使用的方式使用它们。

    “锁”是指具有获取和释放原语的东西,这些原语和原语保持某些锁属性。 例如 专用或单作者/多读者。

    “监视程序”是一种机制,可确保在任何给定时间只有一个线程可以执行给定的代码段。 可以使用锁(和“条件变量”,允许线程等待或通知满足条件的其他线程)来实现此功能,但它不仅仅是锁。 实际上,在Java情况下,不能直接访问监视器使用的实际锁。 (您不能说“ Object.lock()”来阻止其他线程获取它,就像使用Java Lock实例一样。)

    简而言之,如果要学究的话,“ monitor”实际上是比“ lock”更好的术语,用于描述Java提供的特性。 但是实际上,这两个术语几乎可以互换使用。

    Stephen C answered 2019-09-24T08:12:08Z

    20 votes

    监视器只是一个对象的术语,其方法可以在多线程环境中安全使用。

    在Monitors上有一篇很棒的Wikipedia文章:

    [http://en.wikipedia.org/wiki/Monitor_(synchronization)]

    如果向下滚动,甚至还会有专门关于Java的部分。

    ulmangt answered 2019-09-24T08:12:54Z

    5 votes

    它的监视器是object周围的synchronized块,它控制对象上的锁定。 这是一个例子

    synchronized (object) {

    while ()

    object.wait(timeout);

    ... // Perform action appropriate to condition

    }

    abbas answered 2019-09-24T08:13:20Z

    4 votes

    尽管现在回答这个问题已经很晚了,但我还是想补充一下,以防万一。

    这是未同步的Java方法中的Java代码的同步块

    public void add(int value){

    synchronized(this){

    this.count += value;

    }

    }

    在示例“ this”中,使用了add方法。同步实例方法将其所属的对象用作监视对象。

    =>在同一监视对象上同步的Java代码块内只能执行一个线程。

    aman answered 2019-09-24T08:14:13Z

    2 votes

    Java虚拟机使用监视器来支持多线程。 监视器通过两个概念实现这一点-运行线程时互斥(这里是“锁定”的地方)和作为线程间通信手段的协调(这里是对象的wait和notify方法的地方)。

    从“ Inside JVM”中阅读以下部分将清除这个疑问,在这里是否很好解释(第20章,线程同步)-

    [https://www.artima.com/insidejvm/ed2/threadsynchP.html]

    adityalad answered 2019-09-24T08:14:53Z

    2 votes

    从Java虚拟机内部引用

    Java虚拟机中的线程在到达时请求锁定   在监视区域的开头。 在Java中,有两种   监视区域:同步语句和同步方法。

    监控

    监视器就像一栋建筑物,其中包含一个可以   一次只能被一个线程占用。 房间通常包含   一些数据。 从线程进入这个房间的时间到它进入的时间   离开后,它可以独占访问房间中的任何数据。 进入   监视程序的建立称为“进入监视程序”。 进入   建筑物内的特殊房间称为“获取显示器”。   占领房间称为“拥有显示器”,然后离开房间   房间被称为“释放显示器”。 离开整个建筑是   称为“退出监视器”。

    监视器除了与少量数据相关联之外,   与一个或多个代码位相关联,在本书中   称为监视区域。

    如前所述,该语言提供了两种内置方法   识别程序中的监视区域:同步语句和   同步方法。 这两种机制,实现了相互   Java虚拟机支持同步的排除方面   机器的指令集。

    为了实现监视器的互斥功能,Java   虚拟机将锁(有时称为互斥锁)与每个   对象和类。 锁就像特权,只有一个线程可以   随时“拥有”。

    允许单个线程多次锁定同一对象。 对于   每个对象,Java虚拟机都会维护一个数量的计数   对象被锁定的次数。 解锁对象的数量为   零。 当线程首次获取锁时,计数为   再次增加到一。 每次线程获得对   同一对象,计数再次增加。

    Zane XY answered 2019-09-24T08:16:16Z

    展开全文
  • 1、为什么会有锁?在看线程同步的问题之前,我们先看一个生活中的小例子:我拿着银行卡去ATM取钱,假如我的卡里有3000块,我取走2000,这个时候,ATM会去银行的数据库里查询我的账户是否有2000以上的余额,如果有...

    1、为什么会有锁?

    在看线程同步的问题之前,我们先看一个生活中的小例子:

    我拿着银行卡去ATM取钱,假如我的卡里有3000块,我要取走2000,这个时候,ATM会去银行的数据库里查询我的账户是否有2000以上的余额,如果有,就会让我取走,不幸的是,这个时候,我女朋友也来银行取钱,只不过她在前台取钱,她直接取走了3000,这个时候我的卡里已经没钱了,而我也肯定也不能取出2000了。

    我们可以这样想,上面例子中的我和女朋友是两个线程,我们在访问同一块资源,也就是一个账户,这个情况下,是不允许在一个线程访问的时候,另一个线程来打断的,就像我在取钱的时候,我女朋友是不能取的,不能打断我。

    我们先来看一段代码:

    public class TestThread01 implements Runnable{

    Timer timer = new Timer();

    public static void main(String[] args) {

    TestThread01 t = new TestThread01();

    Thread t1 = new Thread(t);

    Thread t2 = new Thread(t);

    t1.setName("t1");

    t2.setName("t2");

    t1.start();

    t2.start();

    }

    public void run(){

    timer.add(Thread.currentThread().getName());

    }

    }

    class Timer{

    private static int num = 0;

    public static void add(String name){

    num++;

    try {

    Thread.sleep(1);

    } catch (InterruptedException e) {

    }

    System.out.println(name +":你是第"+num+"使用timer的线程");

    }

    }

    上面的代码我们就能看出两个线程去访问同一个资源,也就是timer的add方法,看一下运行结果:

    t1:你是第2使用timer的线程

    t2:你是第2使用timer的线程

    结果为什么是这样呢?

    我们分析一下:

    t1启动,访问add方法,num++变为1,这时,t1睡眠,t2启动,t2访问add,num是1,++之后变为2,t2睡眠,t1再继续访问,打印“t1:你是第2使用timer的线程”,然后t1结束,t2继续打印“t2:你是第2使用timer的线程”。

    我们这就见到了线程的打断,有的人可能会说是因为sleep了一毫秒,所以才会这样,其实不然,如果没有sleep,也有可能会被打断,也有可能会正确执行。

    2、对象互斥锁的用法?

    解决方法01:给可能竞争的资源对象加上互斥锁,synchronized (this),锁定当前对象。

    class Timer{

    private static int num = 0;

    public void add(String name){

    synchronized (this) {

    num++;

    try {

    Thread.sleep(1);

    } catch (InterruptedException e) {

    }

    System.out.println(name +":你是第"+num+"使用timer的线程");

    }

    }

    }

    这时的执行结果:

    t1:你是第1使用timer的线程

    t2:你是第2使用timer的线程

    解决方法02:给竞争的方法加上锁

    class Timer{

    private static int num = 0;

    public synchronized void add(String name){

    num++;

    try {

    Thread.sleep(1);

    } catch (InterruptedException e) {

    }

    System.out.println(name +":你是第"+num+"使用timer的线程");

    }

    }

    结果也是对的。

    展开全文
  • 1.为什么要同步访问数据?  当两个或以上的线程需要共享对同一数据的存取,可能会发生共享数据的讹误。 2.实现同步的方式  2.1 ReentrantLock类  School类: class School{ private int stuNum; ...
  • 1.为什么要加锁:解决多线程操作共享数据时的数据安全问题; 2.的分类:类对象锁 对象锁:在 Java 中,每个对象都会有一个 monitor 对象,这个对象其实就是 Java 对象,通常会被称为“内置”或“对象锁”。...
  • 展开全部wait是让使用wait方法的对象等待,暂时先把对象锁给让出来,给其它持有该对象用,其它对象用完后再636f707962616964757a686964616f31333337396235告知(notify)等待的那个对象可以继续执行了,因此,只有...
  • 对象锁的概念通过图理解一下,多个线程要操作同一个对象的场景 图1: 图2: 图3: 解释:● 钥匙是什么,可以理解为线程的执行资格,拥有cpu时间片等资源。● 可是对象的‘锁芯’(对象独占权)只有一个,...
  • Java线程中的对象互斥

    千次阅读 2018-01-07 15:16:36
    1、为什么会有锁? 在看线程同步的问题之前,我们先看一个生活中的小例子: 我拿着银行卡去ATM取钱,假如我的卡里有3000块,我取走2000,这个时候,ATM会去银行的数据库里查询我的账户是否有2000以上的余额,...
  • 比如一个线程获得了某个对象,此时这个对象锁还没有释放,当其再次想获取这个对象的时候还是可以获取的,如果不可重入的话,就会造成死锁。同一个线程每次获取的计数器都自增1,所以等到的...
  • 上一篇文章我们通过一个实例来说明了并发编程为什么要做同步处理,下面我们再来巩固一下。  对象如果拥有可变状态的变量,并且被多线程访问,那么这个时候我们要对可变状态变量的状态改变做原子操作处理。  机制...
  • 在多消费者模式中,消费者pop方法notify随机通知一个SysStack对象等待池中的线程,使其进入SysStack对象池中竞争获取该对象。产生错误的关键原因在于notify通知到的线程既可能是生产者线程有可能是消费者...
  • Java线程 - 机制

    2017-07-20 11:36:24
    为什么要锁如果多个线程修改同一个数据对象,那么会对数据造成破坏,出现“意料之外”的结果,显然不是我们想要,所以我们需要线程同步,也就是需要一把“”。 举个例子:package com.johan.syncthread;public ...
  • Java线程的同步与

    2018-11-29 09:52:03
    文章目录为什么要同步处理线程?同步处理synchronized处理同步问题使用同步代码块使用同步方法synchronized对象锁同一个对象全局代码段)使用类的静态同步方法在代码块中当前Class对象synchronized实现...
  • 线程并发与并行进程与线程为什么要线程区别线程的生命周期锁锁池(多个线程想要拿到对象A同步方法,但是每次只有一个能拿到,所以其他线程就在池中等待)等待池synchronized同步关键字volatile关键字synchronized...
  • Java线程_类(静态)的实现及讨论

    千次阅读 2014-01-09 15:20:16
    然后为什么要有静态? 因为静态方法是属于类的,即对于静态方法而言是没有对象引用的概念的,那么此时就无法使用对象来对静态方法进行锁定了。我们可以做这样的考虑,就是既然静态方法是属于类的,那么我们是否...
  • 我的疑问是:被锁定对象为什么要用static修饰呢?不用static就不住,不能出现死锁了。 public class TestDeadLock implements Runnable{ public int flag = 0; _static_ Object o1 = new ...
  • java线程同步

    2021-02-01 12:43:47
    为什么要了解线程同步? 多个线程执行的不确定性引起执行结果的不稳定性 多个线程对账本的共享,会造成操作不完整性,会破坏数据 例如:两个人同时取银行卡的钱 需要保证事物的原子性 方式一:同步代码块 ...
  • 线程同步,为什么要引入线程同步? 多个线程同时访问共享资源时候,如果没有先来后到,可能造成结果的不可再现性,使得结果背离预期的结果,例如多人抢少量票,银行取钱等. 线程同步的实现是依靠队列和来实现的 java中的...
  • Java中当线程使用了wati 、 notify后,就自动升级总量级了,这时会使用操作系统提供的monitor对象。monitor对象内有waitSet和entryList. 其中 waitSet 中的对象,只能由notify或者notifyAll唤醒后才会去争夺...
  • 为什么要有同步呢? 我们从之前多线程的一个例子来看:有很多用户都分别在进行交易,假若其中一个线程,在正在进行存钱操作,但是还未结束的时候,它在CPU的时间片就已经用完了,这个线程被中断了!而他还没把存的钱...
  • 先看下面例子 再说为什么要线程的同步 class TestThreadCount{ static int cnt=0; public static void main(String[] args) { final int NUM=5000; Thread[] threads =new Thread[NUM]; for (int i=0;i&...
  • 1.为什么要使用synchronized?在并发编程中存在线程安全问题,主要原因有:1.存在共享数据2.多线程共同操作共享数据。关键字synchronized可以保证在同一时刻,只有一个线程可以执行某个方法或某个代码块,同时...
  • java

    2020-04-17 14:39:43
    为什么要引入偏向? 因为经过HotSpot的作者大量的研究发现,大多数时候是不存在竞争的,常常是一个线程多次获得同一个,因此如果每次都要竞争会增大很多没有必要付出的代价,为了降低获取的代价,才引入的...
  • Java - 和监视器有什么区别?

    万次阅读 2019-08-19 16:49:31
    回答这个问题,你必须深入理解Java的多线程底层是如何工作的。 简短的答案是,锁为实现监视器提供必要的支持。详细答案如下。 锁(Lock) 逻辑上锁是对象内存堆中头部的一部分数据。JVM中的每个对象都有一个锁...
  • 为什么要整 局部变量呢? 我的理解:局部变量 意味着 不会发生 并发的更新,只有一个线程,能够保证数据 不会遭到破坏。为每个线程都创建局部对象 ,又太浪费了。 ThreadLocal 辅助类 为各个线程提供各自的实例。 ...
  • Java线程的同步

    2018-06-20 21:09:24
    一、同步:考虑多个线程对同一个资源的更改二、为什么要实现线程之间的同步? 当一个线程对资源更改一半时,还未放入结果中,因为时间片到等原因,线程终止;另一个线程有开始执行对改资源进行更改,未放入有终止,...
  • java线程总结

    2019-03-09 11:55:29
    文章目录多线程线程池满了如何处理额外的请求同一个对象的两个同步方法能否被两个线程同时调用为什么要用线程池悲观和乐观的区别,怎么实现什么是线程死锁,死锁如何产生,如何避免线程死锁线程池用过吗,都有...
  • 线程为什么要使用同步? 当一个Java项目运行的时候,Java是支持多线程并发的,当多个线程同事访问一个可共享资源的时候,将会导致数据的bu不准确,因此加入同步来避免该线程没有执行结束前被别的线程调用,达到...
  • 对象被一个线程持有后,其他线程调用该对象的该方法,就必须进入等待池,等待当前线程执行完毕后,由系统来决定选中谁接下来继续执行。这种方法非常的直观,原理也非常的清晰。那么,Doug Lea为什么会额外...

空空如也

空空如也

1 2 3 4 5 ... 13
收藏数 251
精华内容 100
关键字:

java线程锁为什么要对象

java 订阅