当前位置: 首页 > 知识库问答 >
问题:

不使用同步的线程的安全队列

乐正涵忍
2023-03-14

我要创建一个程序,给定N个线程,这些线程可以在队列中插入或删除一个元素,但是线程访问队列是有条件的:

    null

我用同步块做的,就像这样:

import java.util.ArrayList;
import java.util.Random;

public class EditorThread extends Thread {

    static int N = 10; // number of threads
    static queue Q = new queue(); // shared queue
    private int number; //number of the thread

    public EditorThread(int n) {
        number = n;
    }

    @Override
    public void run() {
        Random r = new Random();

        while (true) {
            int t = r.nextInt(2);
            if (t == 1) {
                int value = Q.get();
                if (value == -1) {
                    System.out.println("The Thread " + number + " couldnt get any element (empty queue)");
                }

                else {
                    System.out.println("The Thread " + number + " got the element " + value );
                }
            }

            else {
                int n = r.nextInt(100);
                Q.put(n);
                System.out.println("The Thread " + number + " inserted the element " + n);
            }

        }

    }

    public static void main(String[] args) {

        for (int i = 0; i < N; i++) {
            Thread t = new EditorThread(i);
            t.start();
        }

    }

}

class queue {
    node head;
    node tail;

    queue() {
        head = tail = null;
    }

    public synchronized int get() {
        if (head == null)
            return -1;
        int r = head.value;
        if (head != tail)
            head = head.next;
        else
            head = tail = null;
        return r;
    }

    public synchronized void put(int i) {
        node n = new node(i);
        if (head == null)
            head = tail = n;
        else {
            tail.next = n;
            tail = n;
        }
    }

}

class node {

    int value;
    node next;

    public node(int value) {
        this.value = value;
    }

}

run void很简单,它只是在插入或删除元素时永远循环。

我的问题是,在不使用synchronized的情况下,我如何遵循那个条件?

没有同步块,怎么可能保证互斥呢?

编辑:我不能使用类似于同步的东西(就像锁一样)

共有1个答案

张瀚漠
2023-03-14

不,是的。

基本上,你需要使用某种形式的同步来做到这一点。没有就没有办法自己做。

然而,在< code > Java . util . concurrent 包中有一些类提供了您所需要的行为,并且在尽可能减少锁定和同步开销的同时做到了这一点。

例如< code>LinkedBlockingQueue。https://docs . Oracle . com/html" target="_blank">javase/7/docs/API/Java/util/concurrent/linkedblockingqueue . html

如果你真的想理解这个东西是如何工作的,你也应该阅读非阻塞算法。维基页面是一个良好的开端。总的来说,很多非常聪明的人知道他们在做什么,但是他们已经在并发包上工作了。穿线很难做对。

https://en.wikipedia.org/wiki/Non-blocking_algorithm

 类似资料:
  • 我尝试使用ArrayList解决生产者和消费者问题(我知道ArrayList是nt threadsafe),我确保使用关键字放置列表,但仍然进入。这就是错误 启动生产者请提供作业详细信息:TestJob作业完成:TestJob Exception位于java.util.ArrayList$itr.checkforcoModification(未知源)位于test.thread.consumer.r

  • 我是java新手。我有点混淆了线程安全和同步。线程安全意味着一个方法或类实例可以被多个线程同时使用,而不会出现任何问题。其中同步意味着一次只能有一个线程运行。 那么它们是如何相互关联的呢?

  • 最近我在读一些关于java并发的书。关于线程安全,如果不可能使一个类变为inmutable,那么可以通过同步它的数据来确保线程安全。 下面的类显然不是线程安全的 然后我可以同步写,但它不会保持线程安全 因为我不仅需要同步写入,还需要同步读取 现在的问题是,通过使用易失性,我可以保证其他线程会看到更新的值,所以这让我认为这个类应该是线程安全的 最后一个类线程安全吗??

  • 问题内容: 当前提供以下实用程序方法来为各种收集接口创建包装器: 类似地,它也有6个重载。 明显的遗漏是这里的实用方法。的确如此,但and 和and 确实有专用于and的实用程序方法。大概是一个有用的抽象,否则它本来就不会存在的,但是还没有实用的方法。 所以问题是: 为什么不提供实用方法的特定原因? 您将如何编写自己的包装器? 浏览OpenJDK版本的源代码似乎表明这只是一个“机械”过程 通常,您

  • 下面是一个解释线程安全性的示例方法: 为了提供线程安全,有几种方法,我更喜欢使用方法。然而 1.我还想知道是否可以通过对必要的变量使用来提供线程安全。如果是,我如何执行此操作? 2.Java中经常使用作为变量和方法参数来提供线程安全性,这是原因之一吗?

  • 例如,我通过 ExecutorService 实例执行可运行块,而该可运行块通过同一 ExecutorService 实例执行一些异步代码。所以我的代码看起来像这样: 这段代码是线程安全的吗,因为ExecutorService没有状态 在我的真实应用程序中,我有一些线程在其中创建了新线程,我想使用一个具有可配置线程池大小的ExecutorService实例(可能是一种不好的做法?)。