【问题标题】:Maintaing value for the variable in a thread in java在java中的线程中维护变量的值
【发布时间】:2016-09-17 04:42:36
【问题描述】:

我正在为多线程应用程序工作,所以我有一个具有一个全局 ArrayList 变量的线程,我正在从数据库中获取值列表并将其分配给该变量。我已将应获取的列表数量限制为 100。在后端我使用的是休眠。

我让这个线程定期在后台运行,但我想做的是,每当这个线程运行时,它将获取下一个 100 个项目列表。而且我不想使用静态并且不想在数据库中维护它,我很困惑如何维护一个计数器,它将告诉我的获取方法接下来要获取的 100 个项目。谁能帮忙,我怎么能做到这一点?以下是我的代码示例,

public class DemoThread implements Runnable {

    private ArrayList <<>> samplePojoList = null;

    @Override
    public void run() {
        MyDaoClass dao = null;

        try { 
            // this dao method fetching list of 100 results from database, 
            // for each iteration i want to fetch next 100 result from 
            // database 
            samplePojoList = dao.getSampleList();
        } catch (Exception e) {}
    }
}

【问题讨论】:

  • 我知道你不想使用静态,但为什么不使用同步的 getInstance 方法创建一个单例呢?
  • @inafalcao 。不 。单例一开始就有很多问题,相关的同步也很困难。通常,最好向构造函数添加参数并传入相关内容。
  • 问题 - 你的线程结束了,然后你重新提交它,对吗?不是连续运行吗?您将不得不在某个时刻将一个变量传递给数据库以告知您在哪里停止(好吧,除非您使用游标做某事,但这是一个稍微不同的问题),所以您不妨传递一个参数也给线程。哦,旁注:数据库本身并没有“下一个”或“上一个”的概念,你必须告诉他们你是否/如何订购......

标签: java multithreading hibernate


【解决方案1】:

在这种情况下,您可以很好地利用ThreadLocal 变量。

请看下面的例子:

private ThreadLocal<Integer> counter = new ThreadLocal<Integer>();

【讨论】:

  • 我应该如何将此变量保持为本地或全局?
  • 全局意思是成员实例变量而不是方法局部变量
【解决方案2】:

这是一个简化的示例,您可以如何将计数器传递给您的线程并在您的消费者线程之间保持同步计数。为了保持线程间计数器计数一致,应该在同步块中访问并增加计数器计数。 我的假设是您希望在所有消费者线程之间共享一个计数器,而不是每个消费者线程一个计数器。

class Counter{
    int count = 0; 
}

class MyThread implements Runnable {
    Counter counter; 
    MyThread(Counter counter){
        this.counter = counter;
    }
    public void run() {
        int count;
        synchronized(counter){
            count = counter.count; 
            counter.count++; 
        }

        // fetch 100 times the value of this counter
        System.out.println(count); // just a stub code
    }
}

public class CounterDemo {

    public static void main(String[] args) {
        Counter counter = new Counter(); 
        MyThread t = new MyThread(counter);
        new Thread(t).start();
    }
}

【讨论】:

    【解决方案3】:

    您可以使用AtomicReference 来实现相同的目的。

    String 的示例代码:

    String initialReference = "value 1";
    
    AtomicReference<String> someRef =
        new AtomicReference<String>(initialReference);
    
    String newReference = "value 2";
    boolean exchanged = someRef.compareAndSet(initialReference, newReference);
    System.out.println("exchanged: " + exchanged);
    

    您可以在上面的示例中将String 替换为ArrayList

    查看这篇 SE 帖子了解更多详情:

    When to use AtomicReference in Java?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-01-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-04
      相关资源
      最近更新 更多