• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

用Java编写互斥锁

用户头像
it1352
帮助1

问题说明

我是计算机科学的新手,正在读一本介绍线程和互斥量的书.我曾尝试用Java编写互斥锁,这似乎在大多数情况下都有效,但是每隔一段时间它都不会起作用.

I'm new to Computer Science and I'm reading a book which introduces threads and mutexes. I've tried programming a mutex in Java which seems to work most of the time but every so often it won't.

在我的代码中,关键部分将数字1到10加到静态变量j,结果为55(如果j从0开始).如果我在关键部分同时运行三个线程,则会得到j的随机最终值,这很有意义.

In my code, the critical section adds on the numbers 1 to 10 to a static variable j which results in 55 (if j starts at 0). If I run three threads at the same time through the critical section, I get random final values of j which makes sense.

但是使用下面的互斥量,大多数时候我得到的最终j值为165(55 * 3),这是我想要的,但是有时我会得到j的随机值.有人可以看看我的代码,看看发生了什么吗?谢谢!

But with the mutex below, most of the time I get a final j value of 165 (55*3) which is what I want but on occasions, I get random values of j. Can someone have a look at my code and see what's going on? Thanks!

public class Mythread extends Thread {

    private static int j = 0;
    private static int mutex = 0;  // Initial value of the mutex is 0;

    @Override
    public void run() {


        while (test_and_set(mutex) == 1) {

            // wait here if mutex is 1
            System.out.println("Thread waiting..");
        } 

        for (int i = 1; i <= 10; i  ) { // Start of Critical section 
            j  = i;                     // 

        }
        System.out.println(j);       // End of Critical section 
                                     // Should add on 55 to j if one thread is running through the CS

       mutex = 0; // Thread that has finished the CS sets the mutex to 0.

    }

    public static int test_and_set(int oldMutexValue) {
        if (mutex == 0) {
            mutex = 1;
        }
        return oldMutexValue;
    }


}

public class Test1 {




    public static void main(String[] args) {

        Mythread thread1 = new Mythread();
        Mythread thread2 = new Mythread();
        Mythread thread3 = new Mythread();
        thread1.start();
        thread2.start();
        thread3.start();

    }



}

正确答案

#1

您正在创建比赛条件,并使用旋转锁.不建议在Java中使用旋转锁.请考虑以下内容:

You're creating a race condition and using a spinning lock. Spinning locks are not recommended in Java. Consider the following:

一个线程开始执行,而其他两个则等待.其他两个线程在等待. 另外两个线程现在都同时设置了互斥锁,并且都开始执行,为您提供了奇数的J值,因为它们同时更改了它.

One thread begins executing while the other two wait. The other two threads wait. The other two threads now both set the mutexes at the same time and both begin executing, giving you an odd value of J because they're both altering it simultaneously.

要修复:

实施Java 同步方法.同步是Java处理线程安全和控制的内部方法.没有旋转锁!

Implement the Java synchronized methodology. Synchronized is Java's internal method of handling thread-safety and control. No spinning locks!

将MyThread更改为以下内容:

Change your MyThread to the following:

public class MyThread extends Thread {
private static int j = 0;

public void run() {
    synchronized(this) {
        for (int i = 1; i <= 10; i  ) {
            j  = i;
        }
    }
    System.out.println(j);
}

同步"可以包围代码的任何关键部分,这些关键部分可能导致竞争状况,数据同时更改等.请注意,缺少特定的锁.请注意,当您同步对该对象的控制时,synced会将其自己的对象作为参数,但是,如果需要,您也可以轻松地将其他对象作为参数,从而为事态锁定提供了更大的灵活性.

Synchronized can surround any critical portions of code that could result in race conditions, simultaneous altering of data, etc. Note the lack of a specific lock. Note that synchronized takes its own object as a parameter, as you are synchronizing control over this object, but you can just as easily take other objects as a parameter, if desired, giving you more flexibility over when things lock down.

其余代码将完全相同!

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /reply/detail/tanhbikfki
系列文章
更多 icon
同类精品
更多 icon
继续加载