2019-4-9
今天面完了快手的大数据系统架构岗(实习),自我感觉不满意
问了java的jvm,了解的不多
ThreadLocal,根本没看过
特此在此处学习
ThreadLocal
创建线程局部变量的类
通常创建的变量可以被任意线程修改,
使用ThreadLocal创建的变量只能够被当前线程访问,其他线程无法修改
Global && Local
Global
在当前线程中,任何一个点都能访问到ThreadLocal的值
Local
该线程的ThreadLocal只能被线程访问,一般情况下其他线程访问不了
用法
创建 支持泛型
ThreadLocal<String> mStringThreadLcoal = new ThreadLocal<>();
Set
mStringThreadLocal.set("xxxxx");
Get
mStringThreadLcoal.get();
完整的使用示例
private void testThreadLocal(){
Thread t = new Thread(){
ThreadLocal<String>mStringThreadLocal = new ThreadLocal<>();
@Override
public void run(){
super.run();
mStringThreadLocal.set("xxx");
sStringThreadLocal.get( );
}
};
t.start();
}
ThreadLocal初始值
为ThreadLocal设置默认的get初始值,需要重写initialValue方法,
ThreadLocal<String>mThreadLocal = new ThreadLocal<String>(){
@Override
protected String initialValue(){
return Thread.currentThread().getName();
}
}
实现原理
Set方法原理
- 获取当前线程
- 利用当前线程作为句柄获取一个ThreadLocalMap的对象
- ThreadLocalMap对象不为空,则设置值,否则创建这个ThreadLocalMap对象并设置值
public void set(T value) {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null)
map.set(this, value);
else
createMap(t, value);
}
利用Thread对象作为句柄获取ThreadLocalMap对象的
ThreadLocalMap getMap(Thread t) {
return t.threadLocals;
}
上面的代码获取的实际上是Thread对象的threadLocals变量
class Thread implements Runnable {
/* ThreadLocal values pertaining to this thread. This map is maintained
* by the ThreadLocal class. */
ThreadLocal.ThreadLocalMap threadLocals = null;
}
如果一开始设置,即ThreadLocalMap对象未创建,则新建ThreadLocalMap对象,并设置初始值。
void createMap(Thread t, T firstValue) {
t.threadLocals = new ThreadLocalMap(this, firstValue);
}
使用InheritableThreadLocal可以实现多个线程访问ThreadLocal的值。
主线程中创建一个InheritableThreadLocal的实例,然后在子线程中得到这个InheritableThreadLocal实例设置的值。
private void testInheritableThreadLocal() {
final ThreadLocal threadLocal = new InheritableThreadLocal();
threadLocal.set("droidyue.com");
Thread t = new Thread() {
@Override
public void run() {
super.run();
Log.i(LOGTAG, "testInheritableThreadLocal =" + threadLocal.get());
}
};
t.start();
}
I/MainActivity( 5046): testInheritableThreadLocal =droidyue.com
使用InheritableThreadLocal可以将某个线程的ThreadLocal值在其子线程创建时传递过去。因为在线程创建过程中,有相关的处理逻辑
//Thread.java
private void init(ThreadGroup g, Runnable target, String name,
long stackSize, AccessControlContext acc) {
//code goes here
if (parent.inheritableThreadLocals != null)
this.inheritableThreadLocals =
ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);
/* Stash the specified stack size in case the VM cares */
this.stackSize = stackSize;
/* Set thread ID */
tid = nextThreadID();
}
2019-4-9 LeetCode203
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode removeElements(ListNode head, int val) {
ListNode dumyHead = new ListNode(-1);
dumyHead.next = head;
ListNode prev = dumyHead;
while(prev.next!=null){
if(prev.next.val==val){
// ListNode delNode = prev.next;
prev.next = prev.next.next;
// delNode.next = null;
}
else{
prev = prev.next;
}
}
return dumyHead.next;
}
}
2019-4-10
今天收到阿里的网面,真的是大佬,佩服佩服,在我认为我熟悉的领域把我打的服服帖帖的
收到一个很奇怪的问题:在docker-file中若先打开一个端口,最后再把这个端口关闭,最终会怎么样emmmm…我真的不懂,刚才搜索了一下也没有人这么用啊,特此记录,日后无聊学习
1
class Solution {
public int[] twoSum(int[] nums, int target) {
for(int i = 0;i<nums.length;i++){
for(int j = i + 1;j<nums.length;j++){
if ( nums[j] + nums [i] == target){
return new int[] {i,j};
}
}
}
throw new IllegalArgumentException("No two sum solution");
}
}
26 删除数组中重复的项
class Solution {
public int removeDuplicates(int[] nums) {
if (nums.length == 0) return 0;
int i = 0;
for (int j = i+1; j < nums.length; j++) {
if (nums[j] != nums[i]) {
// i++;
nums[++i] = nums[j];
}
}
return i + 1;
}
}
2019-4-11
27 移除元素
class Solution {
public int removeElement(int[] nums, int val) {
int i = 0;
for(int j = i; j < nums.length ; j++){
if(nums[j] != val){
nums[i++] = nums[j];
}
}
return i;
}
}
26 删除重复的项
class Solution {
public int removeDuplicates(int[] nums) {
if (nums.length == 0) return 0;
int i = 0;
for (int j = i+1; j < nums.length; j++) {
if (nums[j] != nums[i]) {
// i++;
nums[++i] = nums[j];
}
}
return i + 1;
}
}
27 移除元素
class Solution {
public int removeElement(int[] nums, int val) {
int i = 0;
for(int j = i ; j < nums.length ; j ++){
if(nums[j] != val){
nums[i++] = nums[j];
}
}
return i;
}
}
35 搜索插入的位置
class Solution {
public int searchInsert(int[] nums, int target) {
int j = 0;
for(int i = j ; i < nums.length ; i++){
if(nums[i] < target){
j ++ ;
}
}
return j;
}
}
数组中两个最大数和
class Solution {
public int maxSubArray(int[] nums) {
int max1=nums[0],max2=0;
if(nums.length >1){
for(int j = 0 ; j < nums.length ; j++){
for(int i = 0; i < nums.length ;i ++){
if(nums[i]>max1){
max1 = nums[i];
}
if(nums[j]>max2&&nums[j] != max1){
max2 = nums[j];
}
}
}
}
else
{return nums[0];}
// int mm = max1 + max2;
return max1 + max2;
}
}
2019-4-12
66 +1
class Solution {
public int[] plusOne(int[] digits) {
int carry = 1;
for( int i = digits.length - 1; i >= 0; i --){
if(carry == 0){
return digits;
}
int temp = digits[i] + carry;
carry = temp / 10;
digits[i] = temp % 10;
}
if(carry == 1 ){
int result[] = new int[digits.length + 1];
result[0] = 1;
return result;
}
return digits;
}
}
2019-04-13
20 ()[] {} 匹配判断
import java.util.Stack;
//这个用栈真是巧妙
class Solution {
public boolean isValid(String s) {
Stack<Character> stack = new Stack<>();
for(int i = 0 ; i < s.length() ; i ++){
char c = s.charAt(i);
if(c == '(' || c == '[' || c == '{')
stack.push(c);
else{
if(stack.isEmpty())
return false;
char topChar = stack.pop();
if(c == ')' && topChar != '(')
return false;
if(c == ']' && topChar != '[')
return false;
if(c == '}' && topChar != '{')
return false;
}
}
return stack.isEmpty();
}
}
今天还帮学妹做了个图标,实在做的太好看了,特此传上来
太好看了吧!老子的少女心都要爆发了