标签: thread-safety

Java线程安全计数器

我正在学习编写线程安全的程序以及如何评估非线程安全的代码.

如果一个类在由多个线程执行时正常运行,则该类被认为是线程安全的.

我的Counter.java不是一个线程安全的,但输出是按照预期从0到9打印的所有3个线程.

谁能解释为什么?以及线程安全如何工作?

public class Counter {

    private int count = 0;

    public void increment() {
        count++;
    }

    public void decrement() {
        count--;
    }

    public void print() {
        System.out.println(count);
    }

}

public class CountThread extends Thread {
    private Counter counter = new Counter();

    public CountThread(String name) {
        super(name);
    }

    public void run() {
        for (int i=0; i<10; i++) {
            System.out.print("Thread " + getName() + " ");
            counter.print();
            counter.increment();
        }
    }

}

public class CounterMain {

    public static void main(String[] …
Run Code Online (Sandbox Code Playgroud)

java multithreading thread-safety

0
推荐指数
2
解决办法
7136
查看次数

离开同步块时自动notify()/ notifyAll()

我一直在考虑向Java语言架构师发送一个提案.

在同步块中

synchronized(lock) {

// If there is no notification before this point
// <--- implicitly put here // lock.notifyAll(); // OR // lock.notify();  
}
Run Code Online (Sandbox Code Playgroud)

线程离开同步块后,它不能再调用lock.notifyAll()/ lock.notify()而不会出现异常.

忘记通知其他线程监视器持有者可能会永远让他们(其他线程)等待(除非他们在等待方法中放置了一些超时).

synchronized(lock) {

     lock.wait(); //<--- this thread may forever freeze here
}
Run Code Online (Sandbox Code Playgroud)

我无法想象这样的行为(在没有明确通知的情况下在同步块的末尾插入隐式通知)是不合需要的.

相同的方法可以应用于同步方法.


如何(技术上)实现此类行为可以有不同的方式,例如:

@autonotify
synchronized(lock) {
...
}

@autonotify
public void synchronized doSomething() {
...
}
Run Code Online (Sandbox Code Playgroud)

要么:

@autonotifyAll
synchronized(lock) {
...
}

@autonotifyAll
public void synchronized doSomething() {
...
}
Run Code Online (Sandbox Code Playgroud)

或者 - 使自动通知成为默认行为,但保留抑制它的能力,例如:

@suppressautonotify
synchronized(lock) {
...
}

@suppressautonotifyAll
public void …
Run Code Online (Sandbox Code Playgroud)

java multithreading thread-safety

0
推荐指数
1
解决办法
1342
查看次数

确保在线程中的notify()之前调用wait(),是否可能?

当我遇到使用wait/notify方法的例子时,我正在查看Kathy Sierra书中的Threading章节:

 class ThreadA {
 public static void main(String [] args) {
 ThreadB b = new ThreadB();
 b.start();

 synchronized(b) {
 try {
    System.out.println("Waiting for b to complete...");
    b.wait();
     } catch (InterruptedException e) {}
 System.out.println("Total is: " + b.total);
 }
}
}

class ThreadB extends Thread { 
 int total;
 public void run() {
  synchronized(this) {
   for(int i=0;i<100;i++) {
   total += i;
   }
  notify();
 }
}
}
Run Code Online (Sandbox Code Playgroud)

运行代码总是产生相同的输出:

等待b完成......总计是:4950

我在ThreadB中修改了run()的synchronized块,添加:

System.out.println("ThreadB is executed"); 
Run Code Online (Sandbox Code Playgroud)

问题是:我为什么一直这样做

"等待b完成......"

之前

"执行ThreadB"

?是不是有可能在主线程之前执行线程b?

java thread-safety race-condition

0
推荐指数
2
解决办法
153
查看次数

同步ScheduledExecutorService触发的线程

我有以下测试项目:

import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class myThreadTest {
    private static final Logger log = LoggerFactory.getLogger(myThreadTest.class);
    private ScheduledExecutorService executorService1 = Executors.newSingleThreadScheduledExecutor();
    private ScheduledExecutorService executorService2 = Executors.newSingleThreadScheduledExecutor();

    private Future<?> task1;
    private Future<?> task2;

    private class Task1 implements Runnable {

        @Override
        public synchronized void run() {
            log.debug("-----------------------");
            for (int i = 0; i < 100; i++) {
                log.debug("{} Hello from Task 1",i);
                try {
                    Thread.sleep(2);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            log.debug("-----------------------"); …
Run Code Online (Sandbox Code Playgroud)

java multithreading synchronization thread-safety

0
推荐指数
1
解决办法
896
查看次数

为什么这个测试应用程序在不同的机器上给出不同 (关于后增量和线程安全)

我听说有人说var ++和++ var这样的语句不是线程安全的,所以我写了一个应用程序进行测试.代码如下:

   unsigned long gCounter = 0;
   const unsigned long WORKS = 1048576;  // pow(2, 20)
   const unsigned long MAX_THREADS = 100;
   const unsigned long WORKER_THREADS = 2;

   unsigned long GetCounter(){
           return gCounter++;
   }

   void *WorkerThread(void *){
           unsigned long items = 0;
           do {
                GetCounter();
                items++;
           } while(items < WORKS);

           printf("Exiting thread: %lu\n", pthread_self());
           return NULL;
    }


    int main(int argc, char* argv[]){
         pthread_t workers[MAX_THREADS];

         //create two threads
         for (int i = 0; i < WORKER_THREADS; i++){
            pthread_create(&workers[i], NULL, WorkerThread, …
Run Code Online (Sandbox Code Playgroud)

c++ linux multithreading gcc thread-safety

0
推荐指数
1
解决办法
130
查看次数

为什么这个多线程代码执行的次数比应该多5倍?

我不明白为什么这个简单的python示例执行的时间比它应该多5倍:/我查看代码2小时,在Google等上搜索...我真的没有看到这里的问题.任何帮助,将不胜感激!

import urllib2
import socket
import Queue
import threading

socket.setdefaulttimeout(10)
verbose = True

hosts = ['game1', 'game2', 'game3', 'game4', 'game5', 'game6']

queue = Queue.Queue()

class ThreadUrl(threading.Thread):

    def __init__(self, queue):
        threading.Thread.__init__(self)
        self.queue = queue

    def run(self):
        while True:
            host = self.queue.get()
            url = 'http://{0}.server.com'.format(host)
            f = urllib2.urlopen(url)
            print f.read(1024)
            self.queue.task_done()


def main():

    for i in range(5):
        t = ThreadUrl(queue)
        t.setDaemon(True)
        t.start()

        for host in hosts:
            queue.put(host)

    queue.join()

if __name__ == '__main__':
    main()
Run Code Online (Sandbox Code Playgroud)

python multithreading thread-safety

0
推荐指数
1
解决办法
99
查看次数

这个类是线程安全的吗?

这个班是一个单身人士.我不太擅长线程安全.这个类是线程安全的吗?省略了一些方法,但它们仅用于一个线程.这里列出的方法将同时从多个线程访问.

public class TermsDto {

    private final static MapSplitter mapSplitter = Splitter
            .on(',').trimResults().omitEmptyStrings()
            .withKeyValueSeparator(":");

    private volatile double factorForOthers = 4;

    private volatile Map<String, Double> factorForTermName = 
            new HashMap<String, Double>();

    public void setFactorForOthers(double factorForOthers) {
        this.factorForOthers = factorForOthers;
    }

    public void setFactorForTermNameMapping(String mapping) {
        HashMap<String, Double> tempFactorForTermName = 
                new HashMap<String, Double>();
        for (Map.Entry<String, String> entry : 
                 mapSplitter.split(mapping).entrySet()) {
            double factor = Double.parseDouble(entry.getValue());
            tempFactorForTermName.put(entry.getKey(), factor);
        }
        factorForTermName = tempFactorForTermName;
    }

}
Run Code Online (Sandbox Code Playgroud)

java collections thread-safety getter-setter

0
推荐指数
1
解决办法
255
查看次数

使用双重锁定实现读写锁

我编写了一个Java ReadWriteLock,读者使用双重检查锁定来获取写锁定.这是不安全的(对于具有延迟实例化的DCL的情况)?

import java.util.concurrent.atomic.AtomicInteger;

public class DCLRWLock {
    private boolean readerAcquiringWriteLock = false;
    private boolean writerLock = false;
    private AtomicInteger numReaders = new AtomicInteger();

    public void readerAcquire() throws InterruptedException {
        while (!nzAndIncrement(numReaders)) {
            synchronized (this) {
                if (numReaders.get() != 0)
                    continue;
                if (readerAcquiringWriteLock) {
                    do {
                        wait();
                    } while (readerAcquiringWriteLock);
                } else {
                    readerAcquiringWriteLock = true;
                    writerAcquire();
                    readerAcquiringWriteLock = false;
                    assert numReaders.get() == 0;
                    numReaders.set(1);
                    notifyAll();
                    break;
                }
            }
        }
    }

    public void readerRelease() {
        if (numReaders.decrementAndGet() == 0)
            writerRelease(); …
Run Code Online (Sandbox Code Playgroud)

java atomic thread-safety readwritelock double-checked-locking

0
推荐指数
1
解决办法
586
查看次数

线程安全的数据结构类的目的是什么?

AFAIK是多线程编程的主要目标,它通过利用多个处理内核来提高性能.关键是最大化并行执行.

当我看到线程安全的通用数据结构类时,我觉得有些讽刺.因为线程安全意味着强制执行串行执行(锁定,原子操作或其他),所以它是反并行的.线程安全意味着序列化被封装并隐藏在类中,因此我们将有更多机会强制执行串行 - 失去性能.在较大(或最大)单元 - 应用程序逻辑中管理这些关键部分会更好.

那么为什么人们想要线程安全的类呢?他们的真正好处是什么?


PS 我的意思是线程安全类是一个只有线程安全的方法,可以安全地从多个线程同时调用.安全意味着它保证正确的读/写结果.正确表示其结果等于单线程执行时的结果.(例如避免ABA问题)

所以我认为我的问题中的术语线程安全包含了定义的串行执行.这就是为什么我对它的目的感到困惑并问了这个问题.

c++ multithreading thread-safety

0
推荐指数
1
解决办法
1283
查看次数

何时为可观察对象调用Dispose

我的项目中有很多代码,如Hit和静音,通过这种方式使用Reactive扩展:

    IDisposable dsp = null;
    dsp = TargetObservable.Subscribe((incomingContent) =>
    {
        if (incomingContent == "something")
        {
            myList.Add(incomingContent);
            dsp.Dispose();
        }
    });
Run Code Online (Sandbox Code Playgroud)

首先,我担心线程的安全性,因为我的Observable非常繁忙并且一直有大量内容推送,但后来,我被告知我应该结合ObserveOn(thread)保证线程安全,我完全同意,所以让我们忘记了线程安全的事情.

在这里,我想知道:

  1. 我应该如何或何时将Dispose称为可观察的.
  2. 什么是满足命中和静音的正确方法,结合一些完整的扩展方法,如Take(count)'TakeWhile(预测)'?
  3. 如果OnComplete()被调用,Dispose()将在内部调用,对吗?然后Observer和Observable之间的引用关系将中断(因为我的observable是一个长寿命的静态实例,引用会导致内存泄漏).

c# multithreading thread-safety system.reactive

0
推荐指数
1
解决办法
406
查看次数