精华内容
下载资源
问答
  • 局部变量(Local variables):在方法内部(包括main()方法)定义的变量是局部变量。所有局部变量都是在方法被调用时在栈中分配空间,系统不会自动对他们进行赋值,所以必须先给局部变量赋初值之后才能使用。全局变量和...

    7b4754e8cbb62756865f216106bc3986.png

    全局变量是编程术语中的一种,源自于变量之分。全局变量既可以是某对象函数创建,也可以是在本程序任何地方创建。全局变量是可以被本程序所有对象或函数引用。

    局部变量(Local variables):在方法内部(包括main()方法)定义的变量是局部变量。所有局部变量都是在方法被调用时在栈中分配空间,系统不会自动对他们进行赋值,所以必须先给局部变量赋初值之后才能使用。

    全局变量和局部变量的区别:

    1、作用域不同

    全局变量具有全局作用域。全局变量只需在一个源文件中定义,就可以作用于所有的源文件。当然,其他不包含全局变量定义的源文件需要用extern 关键字再次声明这个全局变量。

    局部变量只有局部作用域,它是自动对象(auto),它在程序运行期间不是一直存在,而是只在函数执行期间存在,函数的一次调用执行结束后,变量被撤销,其所占用的内存也被收回。

    2、初始值不同

    全局变量=有初始值

    局部变量=无初始值

    3、声明上不同

    全局变量=在一个类中不允许声明同名变量

    局部变量=在一个方法中不允许声明同名变量

    (同类不同方法中就可以声明同名的)

    4、优先级不同

    两类变量同名时,局部变量的有限级高

    (就近原则)

    展开全文
  • 局部变量(Local variables):在方法内部(包括main()方法)定义的变量是局部变量。所有局部变量都是在方法被调用时在栈中分配空间,系统不会自动对他们进行赋值,所以必须先给局部变量赋初值之后才能使用。全局变量和...

    7b4754e8cbb62756865f216106bc3986.png

    全局变量是编程术语中的一种,源自于变量之分。全局变量既可以是某对象函数创建,也可以是在本程序任何地方创建。全局变量是可以被本程序所有对象或函数引用。

    局部变量(Local variables):在方法内部(包括main()方法)定义的变量是局部变量。所有局部变量都是在方法被调用时在栈中分配空间,系统不会自动对他们进行赋值,所以必须先给局部变量赋初值之后才能使用。

    全局变量和局部变量的区别:

    1、作用域不同

    全局变量具有全局作用域。全局变量只需在一个源文件中定义,就可以作用于所有的源文件。当然,其他不包含全局变量定义的源文件需要用extern 关键字再次声明这个全局变量。

    局部变量只有局部作用域,它是自动对象(auto),它在程序运行期间不是一直存在,而是只在函数执行期间存在,函数的一次调用执行结束后,变量被撤销,其所占用的内存也被收回。

    2、初始值不同

    全局变量=有初始值

    局部变量=无初始值

    3、声明上不同

    全局变量=在一个类中不允许声明同名变量

    局部变量=在一个方法中不允许声明同名变量

    (同类不同方法中就可以声明同名的)

    4、优先级不同

    两类变量同名时,局部变量的有限级高

    (就近原则)

    展开全文
  • ThreadLocal翻译成中文比较准确的叫法应该:线程局部变量。这个玩意有什么用处,或者说为什么要有这么一个东东?先解释一下,在并发编程的时候,成员变量如果不做任何处理其实线程不安全的,各个线程都在操作同...

    ThreadLocal翻译成中文比较准确的叫法应该是:线程局部变量。

    这个玩意有什么用处,或者说为什么要有这么一个东东?先解释一下,在并发编程的时候,成员变量如果不做任何处理其实是线程不安全的,各个线程都在操作同一个变量,显然是不行的,并且我们也知道volatile这个关键字也是不能保证线程安全的。那么在有一种情况之下,我们需要满足这样一个条件:变量是同一个,但是每个线程都使用同一个初始值,也就是使用同一个变量的一个新的副本。这种情况之下ThreadLocal就非常使用,比如说DAO的数据库连接,我们知道DAO是单例的,那么他的属性Connection就不是一个线程安全的变量。而我们每个线程都需要使用他,并且各自使用各自的。这种情况,ThreadLocal就比较好的解决了这个问题。

    我们从源码的角度来分析这个问题。

    首先定义一个ThreadLocal:

    ThreadLocal tl = ThreadLocal Connection initConn = = DriverManager.getConnection("url, name and password"=( ==

    package java.lang;import java.lang.ref.*;import java.util.concurrent.atomic.AtomicInteger;public class ThreadLocal { private final int threadLocalHashCode = nextHashCode(); private static AtomicInteger nextHashCode =new AtomicInteger();private static final int HASH_INCREMENT = 0x61c88647;private static int nextHashCode() {return nextHashCode.getAndAdd(HASH_INCREMENT);

    }protected T initialValue() {return null;

    }public ThreadLocal() {

    }public T get() {

    Thread t = Thread.currentThread();

    ThreadLocalMap map = getMap(t);if (map != null) {

    ThreadLocalMap.Entry e = map.getEntry(this);if (e != null)return (T)e.value;

    }return setInitialValue();

    }private T setInitialValue() {

    T value = initialValue();

    Thread t = Thread.currentThread();

    ThreadLocalMap map = getMap(t);if (map != null)

    map.set(this, value);elsecreateMap(t, value);return value;

    }public void set(T value) {

    Thread t = Thread.currentThread();

    ThreadLocalMap map = getMap(t);if (map != null)

    map.set(this, value);elsecreateMap(t, value);

    } public void remove() {

    ThreadLocalMap m = getMap(Thread.currentThread()); if (m != null)

    m.remove(this);

    }ThreadLocalMap getMap(Thread t) {return t.threadLocals;

    }void createMap(Thread t, T firstValue) {

    t.threadLocals = new ThreadLocalMap(this, firstValue);

    }static ThreadLocalMap createInheritedMap(ThreadLocalMap parentMap) {return new ThreadLocalMap(parentMap);

    }T childValue(T parentValue) {throw new UnsupportedOperationException();

    }static class ThreadLocalMap {static class Entry extends WeakReference {/** The value associated with this ThreadLocal. */Object value;

    Entry(ThreadLocal k, Object v) {super(k);

    value = v;

    }

    }private static final int INITIAL_CAPACITY = 16;private Entry[] table;private int size = 0;private int threshold; // Default to 0private void setThreshold(int len) {

    threshold = len * 2 / 3;

    }private static int nextIndex(int i, int len) {return ((i + 1 < len) ? i + 1 : 0);

    }private static int prevIndex(int i, int len) {return ((i - 1 >= 0) ? i - 1 : len - 1);

    }ThreadLocalMap(ThreadLocal firstKey, Object firstValue) {

    table = new Entry[INITIAL_CAPACITY];int i = firstKey.threadLocalHashCode & (INITIAL_CAPACITY - 1);

    table[i] = new Entry(firstKey, firstValue);

    size = 1;

    setThreshold(INITIAL_CAPACITY);

    }private ThreadLocalMap(ThreadLocalMap parentMap) {

    Entry[] parentTable = parentMap.table;int len = parentTable.length;

    setThreshold(len);

    table = new Entry[len];for (int j = 0; j < len; j++) {

    Entry e = parentTable[j];if (e != null) {

    ThreadLocal key = e.get();if (key != null) {

    Object value = key.childValue(e.value);

    Entry c = new Entry(key, value);int h = key.threadLocalHashCode & (len - 1);while (table[h] != null)

    h = nextIndex(h, len);

    table[h] = c;

    size++;

    }

    }

    }

    }private Entry getEntry(ThreadLocal key) {int i = key.threadLocalHashCode & (table.length - 1);

    Entry e = table[i];if (e != null && e.get() == key)return e;elsereturn getEntryAfterMiss(key, i, e);

    }private Entry getEntryAfterMiss(ThreadLocal key, int i, Entry e) {

    Entry[] tab = table;int len = tab.length;while (e != null) {

    ThreadLocal k = e.get();if (k == key)return e;if (k == null)

    expungeStaleEntry(i);elsei = nextIndex(i, len);

    e = tab[i];

    }return null;

    }private void set(ThreadLocal key, Object value) {Entry[] tab = table;int len = tab.length;int i = key.threadLocalHashCode & (len-1);for (Entry e = tab[i];

    e != null;

    e = tab[i = nextIndex(i, len)]) {

    ThreadLocal k = e.get();if (k == key) {

    e.value = value;return;

    }if (k == null) {

    replaceStaleEntry(key, value, i);return;

    }

    }

    tab[i] = new Entry(key, value);int sz = ++size;if (!cleanSomeSlots(i, sz) && sz >= threshold)

    rehash();

    }private void remove(ThreadLocal key) {

    Entry[] tab = table;int len = tab.length;int i = key.threadLocalHashCode & (len-1);for (Entry e = tab[i];

    e != null;

    e = tab[i = nextIndex(i, len)]) {if (e.get() == key) {

    e.clear();

    expungeStaleEntry(i);return;

    }

    }

    }private void replaceStaleEntry(ThreadLocal key, Object value, int staleSlot) {

    Entry[] tab = table;int len = tab.length;

    Entry e;int slotToExpunge = staleSlot;for (int i = prevIndex(staleSlot, len);

    (e = tab[i]) != null;

    i = prevIndex(i, len))if (e.get() == null)

    slotToExpunge = i;for (int i = nextIndex(staleSlot, len);

    (e = tab[i]) != null;

    i = nextIndex(i, len)) {

    ThreadLocal k = e.get();if (k == key) {

    e.value = value;

    tab[i] = tab[staleSlot];

    tab[staleSlot] = e;if (slotToExpunge == staleSlot)

    slotToExpunge = i;

    cleanSomeSlots(expungeStaleEntry(slotToExpunge), len);return;

    }if (k == null && slotToExpunge == staleSlot)

    slotToExpunge = i;

    }tab[staleSlot].value = null;

    tab[staleSlot] = new Entry(key, value);if (slotToExpunge != staleSlot)

    cleanSomeSlots(expungeStaleEntry(slotToExpunge), len);

    }private int expungeStaleEntry(int staleSlot) {

    Entry[] tab = table;int len = tab.length;tab[staleSlot].value = null;

    tab[staleSlot] = null;

    size--; Entry e;int i;for (i = nextIndex(staleSlot, len);

    (e = tab[i]) != null;

    i = nextIndex(i, len)) {

    ThreadLocal k = e.get();if (k == null) {

    e.value = null;

    tab[i] = null;

    size--;

    } else {int h = k.threadLocalHashCode & (len - 1);if (h != i) {

    tab[i] = null;while (tab[h] != null)

    h = nextIndex(h, len);

    tab[h] = e;

    }

    }

    }return i;

    }private boolean cleanSomeSlots(int i, int n) {boolean removed = false;

    Entry[] tab = table;int len = tab.length;do {

    i = nextIndex(i, len);

    Entry e = tab[i];if (e != null && e.get() == null) {

    n = len;

    removed = true;

    i = expungeStaleEntry(i);

    }

    } while ( (n >>>= 1) != 0);return removed;

    }private void rehash() {

    expungeStaleEntries();// Use lower threshold for doubling to avoid hysteresisif (size >= threshold - threshold / 4)

    resize();

    }private void resize() {

    Entry[] oldTab = table;int oldLen = oldTab.length;int newLen = oldLen * 2;

    Entry[] newTab = new Entry[newLen];int count = 0;for (int j = 0; j < oldLen; ++j) {

    Entry e = oldTab[j];if (e != null) {

    ThreadLocal k = e.get();if (k == null) {

    e.value = null; // Help the GC} else {int h = k.threadLocalHashCode & (newLen - 1);while (newTab[h] != null)

    h = nextIndex(h, newLen);

    newTab[h] = e;

    count++;

    }

    }

    }

    setThreshold(newLen);

    size = count;

    table = newTab;

    }private void expungeStaleEntries() {

    Entry[] tab = table;int len = tab.length;for (int j = 0; j < len; j++) {

    Entry e = tab[j];if (e != null && e.get() == null)

    expungeStaleEntry(j);

    }

    }

    }

    }

    这样子,都是用同一个连接,但是每个连接都是新的,是同一个连接的副本。

    那么实现机制是如何的呢?

    1、每个Thread对象内部都维护了一个ThreadLocalMap这样一个ThreadLocal的Map,可以存放若干个ThreadLocal

    /* ThreadLocal values pertaining to this thread. This map is maintained

    * by the ThreadLocal class. */ThreadLocal.ThreadLocalMap threadLocals = null;

    2、当我们在调用get()方法的时候,先获取当前线程,然后获取到当前线程的ThreadLocalMap对象,如果非空,那么取出ThreadLocal的value,否则进行初始化,初始化就是将initialValue的值set到ThreadLocal中。

    public T get() {

    Thread t = Thread.currentThread();

    ThreadLocalMap map = getMap(t);if (map != null) {

    ThreadLocalMap.Entry e = map.getEntry(this);if (e != null)return (T)e.value;

    }return setInitialValue();

    }

    3、当我们调用set()方法的时候,很常规,就是将值设置进ThreadLocal中。

    4、总结:当我们调用get方法的时候,其实每个当前线程中都有一个ThreadLocal。每次获取或者设置都是对该ThreadLocal进行的操作,是与其他线程分开的。

    5、应用场景:当很多线程需要多次使用同一个对象,并且需要该对象具有相同初始化值的时候最适合使用ThreadLocal。

    6、其实说再多也不如看一下源码来得清晰。如果要看源码,其中涉及到一个WeakReference和一个Map,这两个地方需要了解下,这两个东西分别是a.Java的弱引用,也就是GC的时候会销毁该引用所包裹(引用)的对象,这个threadLocal作为key可能被销毁,但是只要我们定义成他的类不卸载,tl这个强引用就始终引用着这个ThreadLocal的,永远不会被gc掉。b.和HashMap差不多。

    展开全文
  • 理由:局部变量是线程内部共享的,每一个线程内的不能访问其他线程的局部变量,但是上诉的情况却违背了这一原则,那么加上final为什么就可以了呢?原因是加上final之后,在创建B线程的时候会把final标记的变量作为...

    局部变量和形参带final。

    在一个线程A中开起另一个线程B,如果线程B要使用线程A的局部变量,那么A的局部变量需要定义成final。理由:局部变量是线程内部共享的,每一个线程内的不能访问其他线程的局部变量,但是上诉的情况却违背了这一原则,那么加上final为什么就可以了呢?原因是加上final之后,在创建B线程的时候会把final标记的变量作为线程B的构造方法的参数传给B,如此一来就解决了此问题,这是一个比较巧妙的做法,通过class文件反编译可以看出这个道理。

    另外Java的String变量比较特殊,他所定义的变量的值全部都存放在常量池里面,不管是不是final的。下面的结果全部为true。并且如果相等都指向同一个地址。

    基本类型的局部变量如果值相同也都指向同一个地址。只有后面的和前面的不想等的时候才会指向新的地址,这就是为什么基本局部变量相互之间不会影响的原因。

    public class StringTest {

    private static String s1 = "123";

    static final String s2 = "123";

    public static void main(String[] args) {

    String s3 = "123";

    final String s4 = "123";

    System.out.println(s1 == s2);

    System.out.println(s3 == s4);

    System.out.println(s1 == s3);

    }

    }

    展开全文
  • 和他相反的局部变量是啥子东东呢?局部变量就是局部的东西,如果全局变量是桌子,局部变量就类似于抽屉,只能在一小部分地方使用,很局限。全局是外面公共场所的凳子,则局部变量就像某个酒店的凳子一样,再酒店内部...
  • 局部变量的作用域:1、主函数main()中定义的变量也只在主函数中有效,而不能因为在主函数中定义在整个文件或程序中有效。主函数也不能使用其他函数中定义的变量。因为主函数也一个函数,它与其他函数平行关系。...
  • 1、在Java中,变量大体分为以下4类:类变量、常量、实例变量、局部变量public class Test { public static int classVar;// 类变量,即静态变量,关键词static     public static final int constant = 10;// ...
  • 什么必须始终在Java中初始化局部变量(包括基元)?为什么必须始终在Java中初始化局部变量(包括基元)? 为什么相同的实例变量不适用?8个解决方案66 votes基本上,要求在读取变量之前为其分配值一件好事。 这意味...
  • 局部变量 何为局部变量局部变量就是方法里定义的变量。 局部变量仅作用在局部区域中,从定义开始到大括号或者return结束,生命周期短。 局部变量存储:基本数据类型变量放在栈中,引用数据类型...
  • 展开全部java易混淆概念之类变量32313133353236313431303231363533e4b893e5b19e31333365643662、实例变量、局部变量类变量、实例...局部变量是类的方法中的变量。Java是一门面向对象编程语言,不仅吸收了C++语言的各...
  • <p>java什么是全局变量,什么是局部变量,这两者之间又怎么区别?</p>
  • Java局部变量final

    千次阅读 2018-10-26 09:25:36
    理由:局部变量是线程内部共享的,每一个线程内的不能访问其他线程的局部变量,但是上诉的情况却违背了这一原则,那么加上final为什么就可以了呢?原因是加上final之后,在创建B线程的时候会把final标记的变量作为...
  • 局部变量一般指在方法体内部定义的变量,其作用域在方法内部有效。 public class Test{ public static void main(String[] args) { int a;//变量a未被初始化,在被使用时会出现编译错误 //int a = 0...
  • 今天要实战的 Java 10 中最重要的特性:局部变量类型推断,大家都知道 var 关键字,但具体怎么使用,及要注意什么要点呢?我们通过几个例子来讲解局部变量类型推断这个新特性!什么是局部变量类型推断var java...
  • 变量-类变量也称为静态变量在类中但使用方法,构造函数或块之外使用static关键字声明的。每个类每个类变量只有一个副本,而不管从中创建了多少个对象。实例变量-实例变量在类中声明,但在方法外部。为堆中的...
  • java中就没有全局变量这个概念,只分为成员变量和局部变量。成员变量:Static修饰成为类变量或静态变量,还有就是方法外的变量。生命周期与类相同。局部变量:就是方法中的变量。生命周期就是再次方法中。但是,很多...
  • 大家在刚学的时候肯定会有一定疑惑,什么是局部变量什么是成员变量?我刚学的时候也分不清楚,大家只需要记住以下这些就足够了! 那局部变量和成员变量的区别到底在哪里呢? 1.定义的位置不一样【重点】 局部...
  • java成员变量是什么

    千次阅读 2019-07-02 07:58:28
    java中 变量分成员变量 和局部变量 成员变量是指这个类的变量,局部变量是类中方法体内定义的变量。
  • 原标题:Java 10 局部变量类型推断是什么? 协作翻译原文:Java 10 Local Variable Type Inference链接:https://developer.oracle.com/java/jdk-10-local-variable-type-inference译者:边城, dreamanzhao, 无若, ...
  • Java 局部内部类访问局部变量什么必须加final关键字 疑问 在Java中,局部内部类如果调用了方法中的变量,那么该变量必须申明为final类型,如果不申明,则编译就会出错。 这里的内部类指的方法内部类或匿名内部...
  • 1.成员变量 在类中定义,用来描述对象将要有什么。 2.局部变量 在类的方法中定义,在方法中临时保存数据。 ...成员变量和局部变量的区别 ... Java不会给局部变量赋予初始值 public class test6 { ...
  • _****写法1:用全局变量 不对 写法2 :用局部变量 对****_ 为什么?最好能解释的详细一点 ``` import java.io.File; import java.util.Scanner; public class Directory{ public static void main(String []args...
  •  java虚拟机栈描述的是java方法执行的内存模型:每个方法在执行的同时都会创建一个栈帧用于存放局部变量表,操作数栈,动态链接,方法出口等信息。局部变量表所需的内存空间在编译期间完成分配,当进入一个方法时,...
  • 按我的理解 size 在方法里面是局部变量 作用整个方法 在外面类变量 作用整个类 但是在这段代码中应该没什么不同吧,因为我只有一个方法,SIZE意思固定的 问题2: 第14行的 files != null && 能不能省掉? ...
  • public void show() {// 局部变量java8开始,如果该变量被内部类引用,java编译器就会默认给该变量加final修饰。// 所以,如果该变量需要被内部类引用,虽然可以省略final,但是在实际开发中最好还是加上final。//...
  • 如今倘若你是java语言的开发人员,你早已将目标储存在了堆内存中,而将局部变量储存在了栈运行内存中,你会怎么做呢?Java 中的自变量分成类自变量,成员函数和局部变量,各自坐落于 JVM 的方法区、堆内存和栈运行...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 3,052
精华内容 1,220
关键字:

java局部变量是什么

java 订阅