繁体   English   中英

无法获取Threadlocal值

[英]Not able to get the Threadlocal value

我正在尝试通过使用threadlocal变量按以下顺序使用三个不同的线程来打印数字0,1、2等:

0- thread 0
1- Thread 1
2- Thread 2
3- thread 0
4- Thread 1
.
.

以下是我将一个整数放入线程本地存储并将其与每个线程递增的原子整数进行比较的代码。

  public class alternate123 
{

public static void main(String as[])
{  
    Object ob = new Object ();AtomicInteger t = new AtomicInteger(0);

    Thread t1 = new Thread ( new printpattern(t,0),"t0");
    Thread t2 = new Thread ( new printpattern(t,1),"t1");
    Thread t3 = new Thread ( new printpattern(t,2),"t2" );

    t1.start();
    t2.start();
    t3.start();



}

}
class printpattern implements Runnable
{
    //Integer t ;
    //Object ob = new Object ();
    AtomicInteger ai;
    private  ThreadLocal<Integer> t = new ThreadLocal<Integer>() ;
    public printpattern(AtomicInteger at,Integer i)
    {
        //
        ai=at;
        t.set(i);
    }
    @Override
    public void run()
    {
        // TODO Auto-generated method stub

        synchronized (ai) { 
        while (true)
        {if (ai.get()%3==
            t.get()) // ----------------------- null pointer exception here 
            {
                try {
                    ai.wait();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            try {
                Thread.sleep(300);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            System.out.println("Current thread id "+Thread.currentThread().getName()+"value of integer is "+ai.get());;
            ai.incrementAndGet();
            ai.notify();
        }
    }
    }

}

我在尝试执行t.get()时得到null,下面是stacktrace:

Exception in thread "t2" java.lang.NullPointerException
    at printpattern.run(alternate123.java:46)
    at java.lang.Thread.run(Thread.java:619)
Exception in thread "t0" java.lang.NullPointerException
    at printpattern.run(alternate123.java:46)
    at java.lang.Thread.run(Thread.java:619)
Exception in thread "t1" java.lang.NullPointerException
    at printpattern.run(alternate123.java:46)
    at java.lang.Thread.run(Thread.java:619)

我正在使用set方法设置threadlocal变量,我怀疑这是错误的。 请让我知道可能是什么问题。

在您的主线程中调用了构造函数,因此为该线程设置了值:您必须在run方法中设置threadlocal值。 只需将整数值(构造函数中的i参数)存储为printpattern类内的字段,然后在run方法中调用t.set(i)。

PS:请将printpattern重命名为PrintPattern-这是一个类。

调用set方法将仅分配当前阈值 d 的值 您正在从主线程设置值。 因此,它将仅在您的主线程中可用。

实际上,在这种情况下, 您仅需要一个ThreadLocal实例,然后就可以将其重用于多个线程。 但是无论哪种方式,从各个线程中设置值都是至关重要的。 (即在您的run方法中)

您可能会以某种方式将ThreadLocal<Integer>对象视为Map<Thread, Integer> ,其中set方法等效于map.put(Thread.currentThread(), value) 这实际上并不是内部的工作方式,但是从功能的角度来看,这几乎就是它的工作方式。

这是一个将threadlocal重用于多个线程的示例 (更改用//CHANGE x注释标记。)

public class Alternate123 {

    public static void main(String as[]) {
        // CHANGE 1: create only 1 threadlocal instance.
        ThreadLocal<Integer> threadLocal = new ThreadLocal<Integer>();

        // CHANGE 2: pass the threadlocal to the individual threads.
        Thread t1 = new Thread(new printpattern(0, threadLocal), "t0");
        Thread t2 = new Thread(new printpattern(1, threadLocal), "t1");
        Thread t3 = new Thread(new printpattern(2, threadLocal), "t2");
        t1.start();
        t2.start();
        t3.start();
    }

}

class printpattern implements Runnable {
    // CHANGE 3: keep track of the initial value
    Integer startValue;
    ThreadLocal<Integer> threadLocal;

    AtomicInteger ai = new AtomicInteger();

    public printpattern(Integer i, ThreadLocal<Integer> threadLocal) {
        // CHANGE 4: don't assign the value to the threadlocal yet.
        // Because we are still in the main-thread when we reach this point.
        this.startValue = i;
        this.threadLocal = threadLocal;
    }

    @Override
    public void run() {
        // CHANGE 5: Assign the initial value to the threadlocal
        // this time we are doing it from within the individual threads.
        if (this.threadLocal.get() == null) {
            this.threadLocal.set(startValue);
        }

        synchronized (ai) {
            while (true) {
                if (ai.get() % 3 == t.get()) {
                    try {
                        ai.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                try {
                    Thread.sleep(300);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                // CHANGE 6: I had to change something here to make it compile. Not really relevant.
                System.out.println("Current thread id " + Thread.currentThread().getName() + "value of integer is ...");

                ai.incrementAndGet();
                ai.notify();
            }
        }
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM