我要创建一个程序,给定N个线程,这些线程可以在队列中插入或删除一个元素,但是线程访问队列是有条件的:
我用同步块做的,就像这样:
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的情况下,我如何遵循那个条件?
没有同步块,怎么可能保证互斥呢?
编辑:我不能使用类似于同步的东西(就像锁一样)
不,是的。
基本上,你需要使用某种形式的同步来做到这一点。没有就没有办法自己做。
然而,在< 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实例(可能是一种不好的做法?)。