用Java编写互斥锁 [英] Programming a mutex in Java

查看:273
本文介绍了用Java编写互斥锁的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是计算机科学的新手,正在读一本介绍线程和互斥量的书.我曾尝试用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();

    }



}

推荐答案

您正在创建比赛条件,并使用旋转锁.不建议在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.

其余代码将完全相同!

希望这会有所帮助!

这篇关于用Java编写互斥锁的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆