volatile和static在多线程中疑问

在单例中静态变量除了存储和用法不同和实例变量不同以外,其是可以相当于volatile 修饰的实例变量

2个回答

你好。不完全是,volatile 只是一个确保,每次读取和写入是,都去认证的核对,并保证读写过程不被系统终端。

static静态变量只会初始化一次,它属于类,而volatile只是修饰变量在多线程中的表现,保持hapeens-before的原则

Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
其他相关推荐
多线程volatile的相关问题
package com.wqx.lang; public class VolatileBoolean extends Thread{ private boolean b = true; @Override public void run() { while(b){ System.out.println(b); } System.out.println("run 结束"); } public static void main(String[] args) throws InterruptedException { VolatileBoolean volatileBoolean = new VolatileBoolean(); volatileBoolean.start(); Thread.sleep(1000); volatileBoolean.b = false; System.out.println("设置 false"); Thread.sleep(1000); } } 为什么线程会被停止,按道理说没有加volatile,线程内存中的b应该还是true才对? 把System.out.println(b);去掉线程又不能够停止,有人能够说明一下为什么会出现这样状况
通过线程将数据库读取的数据放在java队列,然后通过多线程处理数据的解决办法
各位大神,求帮助,我现在项目中有一个需求,对9张单表的有增删改的操作的时候 将数据通过单线程的方式放入java队列中,然后通过多线程的方式下发。我会建一张 下发失败的表,如果通过java队列下发失败了的数据会存入下发表,等待下次下发。 现在我做的是在这9张表有增、删、改、操作的时候通过队列管理器将数据放入队列中,然后用多线程的方式下发。 现在求助大家的是前面的步骤,就是队列管理器中的功能,也就是单线程放数据到队列中及通过队列多线程下发的步骤。由于小弟未在项目中真正的写过多线程的实例,特真心请求大神帮助,帮忙修改下代码的逻辑,小弟写了个初稿,肯定未完善,请大神帮忙完善下,多多考虑,非常感谢大家了! 以下是我初写的队列管理器的功能。请大神帮忙修改下,谢了 public class TaskQueueManage { public static BlockingQueue<Object> queue; private TaskQueueManage() { queue = new LinkedBlockingQueue<Object>(); } private static volatile TaskQueueManage instance; public static TaskQueueManage getIstance() { if (instance == null) { synchronized (TaskQueueManage.class) { if (instance == null) { instance = new TaskQueueManage(); } } } return instance; } //用线程将数据库中有增、删 、改操作的数据放入队列中 public static void put(final Object obj) { Runnable runnable = new Runnable() { @Override public void run() { try { //将读取的数据库的数据放入队列 queue.put(obj); } catch (Exception e) { } } }; Thread thread = new Thread(runnable); thread.start(); } //用多线程取出队列中的数据 public static void take() { //下发用线程池,将用多线程进行下发 ExecutorService service = Executors.newScheduledThreadPool(5); Runnable runnable = new Runnable() { @Override public void run() { try { Object obj = queue.take(); //取出数据,待操作.... } catch (Exception e) { } } }; service.equals(runnable); } } 真心求大家的帮助,谢谢了!
java多线程数据可见性问题
下面这个程序缓存一致性问题,initflag第二个线程更改为true后,第一个线程while循环中如果没有输出那个代码或者加个同步块就跳不出循环。对于synchronized不应该是针对同一个监视器对象的话会保持内存可见吗? 再者initflag没有在同步代码块中包含,而是在while条件中,为什么线程1能够将自己的工作内存副本清除去主内存获取到线程2更改后的值呢?(不用volatile关键字) package myTest; public class ThreadMesiTest { public static boolean initFlag = false; public static void main(String[] args) throws InterruptedException { Thread thread1 = new Thread(new Runnable() { @Override public void run() { while(!initFlag){ System.out.println("进来了"); } System.out.println("获取到了新值跳出循环了"); } }); thread1.start(); Thread.sleep(5000); Thread thread2 = new Thread(new Runnable() { @Override public void run() { initFlag = true; System.out.println("更新啦falg的值"); } }); thread2.start(); } }
关于println和sleep 会在不适用volatile 关键字的情况下跳出循环?
``` package com.test; import java.util.concurrent.TimeUnit; public class test1 { private static boolean is = true; public static void main(String[] args) { new Thread(new Runnable() { @Override public void run() { int i = 0; while(test1.is){ i++; //println 是synchronized 的,会强制刷新住内存的变量值到线程栈? System.out.println("1"); /* * sleep 会使is的值 在线程栈中失效,从新load 住内存的值? try { TimeUnit.MICROSECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); }*/ } } }).start(); try { TimeUnit.MICROSECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } new Thread(new Runnable() { @Override public void run() { is = false; } }).start(); } } ``` 上面这段代码,在循环中加入println 或者 sleep 都会使循环终止。为什么?
一个java多线程的问题
为什么代码中线程VolatileExample 不会终止 ``` package thread; public class VolatileExample extends Thread{ private static boolean flag = false; @Override public void run() { while (!flag) { //System.out.println(1); } } public static void main(String[] args) throws InterruptedException { VolatileExample v = new VolatileExample(); v.start(); Thread.sleep(1000); flag = true; } } ``` 而 ``` package thread; public class VolatileExample extends Thread{ private static boolean flag = false; @Override public void run() { while (!flag) { System.out.println(1); } } public static void main(String[] args) throws InterruptedException { VolatileExample v = new VolatileExample(); v.start(); Thread.sleep(1000); flag = true; } } ``` 却可以正常终止。 还有这样 ``` package thread; public class VolatileExample extends Thread{ private static volatile boolean flag = false; @Override public void run() { while (!flag) { //System.out.println(1); } } public static void main(String[] args) throws InterruptedException { VolatileExample v = new VolatileExample(); v.start(); Thread.sleep(1000); flag = true; } } ``` 线程也可以正常终止。。。求大神指导。。
java多线程中的join问题
各位大神,本人java小菜鸟。学习java遇到一点问题,下面的代码中,已经使用了join方法,为什么显示的结果不是1000呢?请前辈指教! ``` public class JoinThread extends Thread { public static volatile int n=0; public void run(){ for(int i=0;i<10;i++,n++){ try{ sleep(2); }catch(Exception e){} } } public static void main(String args[])throws Exception{ Thread[] threads=new Thread[100]; for(int i=0;i<threads.length;i++) threads[i]=new JoinThread(); for(int i=0;i<threads.length;i++) threads[i].start(); for(int i=0;i<threads.length;i++) threads[i].join(); System.out.println("n="+JoinThread.n); } } ```
设计模式中单例模式的双重验证模式的问题
双重验证代码: /** * 双重验证懒汉模式(线程安全) * */ public class LazyAgainSingletonPattern { private static volatile LazyAgainSingletonPattern pattern; private LazyAgainSingletonPattern(){ } public static LazyAgainSingletonPattern getInstance() throws InterruptedException { if(pattern == null){ Thread.sleep(1000); synchronized (LazyAgainSingletonPattern.class){ if(pattern == null){ pattern = new LazyAgainSingletonPattern(); } } } return pattern; } } 可以改为单重验证会有什么问题呢? 如:public class LazyAgainSingletonPattern { private static volatile LazyAgainSingletonPattern pattern; private LazyAgainSingletonPattern(){ } public static LazyAgainSingletonPattern getInstance() throws InterruptedException { Thread.sleep(1000); synchronized (LazyAgainSingletonPattern.class){ if(pattern == null){ pattern = new LazyAgainSingletonPattern(); } } return pattern; } } 少了一重验证,多线程下测试时结果都一样,都是单例对象 测试代码: public class Test { public static void main(String[] args) { for(int i = 0;i < 10; i++){ new Thread(()->{ LazyAgainSingletonPattern singletonPattern = null; try { singletonPattern = LazyAgainSingletonPattern.getInstance(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(singletonPattern); }).start(); } } } 输出结果都一样,请问双重验证为什么不能改为单重验证呢
这段java多线程代码为什么后来不输出东西了呢?
public class Test4 { private static boolean b; private static int count = 0; public static void main(String[] args) { new Thread(() -> { while (true){ count++; if(b == !b){ System.out.println(new Date()+":"+count); } } }).start(); new Thread(() -> { while (true) { b=!b; } } ).start(); } } 上面这段代码,第一个线程比较b和!b,第二个线程不断改变b的值, 讲道理的话,如果“取出第一个b”和“取出第二个b”这两个行为发生 在第二个线程改变b之前和之后,这时候b==!b条件是成立的。 这个程序会不断地输出count的值, 但是事实上,这段代码在输出一段时间之后,就不会输出了, 也就意味着这段代码只有一开始的时候会发生 b==!b这样的事情, 后来这件事情就再也不发生了, 本人对此感到不解,请各位大佬解惑。 另外,如果把b修饰为volatile ,那么就会一直输出下去。
Java写交易客户端(多线程、对象数据传送等简单问题)
有如下几个类: 1、Ticker类 //此Ticker为简单java类,其属性与服务器传来的json字段对应,通过Decoder类反系列化json //反系列化以后的数据,用以做逻辑判断,符合逻辑,则向服务器发出某种请求 public class Ticker implements Serializable { private static final long serialVersionUID = 2015022601L; private volatile Double buy; private volatile Double contractId; public void setBuy(Double buy) { this.buy = buy; } public void setContractId(Double contractId) { this.contractId = contractId; } } public Double getBuy() { return buy; } public BigDecimal getContractId() { return contractId; } public Ticker() { super(); } public Ticker( Double buy, Double contractId) { this.buy = buy; this.contractId = contractId; } } 2、Decoder类 //此类接收服务器传来的json(msg字符串),采用Gson将其反系列化 //此msg消息一直不断推送过来,比如第一次推送{buy:100,contractId:20},下一次可能是{buy:50,contractId:305} public class Decoder implements Abc{ @Override public void onReceive(String msg){ System.out.println(msg); if (msg.contains("ticker")) { Gson gson=new Gson(); Ticker ticker=gson.fromJson(msg, Ticker.class); //反系列化后得到的数据存于ticker对象 } } } 3、Test类 //此类利用反系列化后的数据进行判断,然后向服务器发出某些请求 public class Test{ 此类里需要用到Decoder里得到的ticker对象的buy及contractId属性值, 比如此类一直在做以下判断 if (buy>contractId){ 向服务器发出一次请求 } } 问题: (1),Test类怎么才能得到Decoder类里实例化的ticker对象的属性值(buy,contractId),是在Ticker加上一个构造方法?还是在Decoder类里写一个方法?或者其他?请给出实际代码。 (付:这是一个线程间通讯的问题么?) (2),Decoder类一直每秒几次的转换服务器推送来的json,每一次得到的ticker对象地址不一样,其ticker只有最近一个的属性有用,这样是不是产生了大量的垃圾,还是说虽然地址不一样,但后产生的ticker自动覆盖了前面的ticker对象? (3),如果此程序采用多线程,同时还使用SWT写了一个UI类,是否要再写一个类用来更新ticker对象的属性到UI界面上(或者采用Eclipse数据绑定的办法)? 现在相当于: Decoder类一直不断在进行json转换, UI类一直在把ticker对象的属性数据更新到UI界面(或者用其他办法更新上去), Test类也一直在使用ticker的属性值进行数据的逻辑判断, 此程序是否应该是至少三个线程?那具体怎么实现多线程(每个类都实现Runnable接口?)?主方法是该放在UI类里,还是放在客服端里(Test类是否可作为客服端)? 请请给出具体多线程实现的代码? (4)如果Test类用于逻辑判断的属性值buy和contractId不采用Decoder类里产生的,而是去UI界面上再次取得,那这个取得过程是否与(2)问的解决办法一样? 真心求教,成功发财了发个大红包!
如何保证多线程操作中对象的内存可见性?
我用一个线程池,对一个队列里的数据操作。如果队列为空,则不开启线程池。队列不为空,拿到其中的数据,用线程池跑任务。这个判断用的while (queue.peek() != null) 现在有一个问题,就是线从队列里拿出数据queue.poll()并执行完操作之后,上面那个判断语句循环回去拿到的queue仍然是非null的,继续循环,但实际上队列里已经没有数据了。我加了volatile也不行,给queue队列加了双重校验锁也不行。一旦循环的次数多了,就报空指针,这该怎么保证多线程下对Queue对象的内存可见? 代码如下,多谢各位大佬 ``` @Component public class TaskThreadPools { @Autowired private ManagerService managerService; @Autowired private OperationLogService operationLogService; private static final org.apache.commons.logging.Log log = LogFactory.getLog(ThreadPools.class); private static volatile Queue<QueueDealStructure> dataQueue; public static Queue<QueueDealStructure> getQueueInstance() { // if (dataQueue == null) { // Object o = "lock"; // synchronized (o) { if (dataQueue == null) { dataQueue = new LinkedList<>(); } // } // } return dataQueue; } public void commitLogPool() { for (int i = 0; i < 5; i++) { QueueDealStructure queueDealStructure = new QueueDealStructure(); queueDealStructure.setKeyIdentity("8"); queueDealStructure.setProperty("000"); getQueueInstance().offer(queueDealStructure); } try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } List<OperationLog> logs = Collections.synchronizedList(new ArrayList<>()); // ReadWriteLock readWriteLock = new ReentrantReadWriteLock(); // Queue<QueueDealStructure> queueDealStructure = getQueueInstance(); if (getQueueInstance().peek() != null) { log.info("========================get poll not null>>"); ExecutorService threadPoolExecutor = Executors.newSingleThreadExecutor(); while (getQueueInstance().peek() != null) { threadPoolExecutor.submit(new Runnable() { @Override public void run() { try { log.info("===============================service start>>"); QueueDealStructure poll = getQueueInstance().poll(); String keyIdentity = poll.getKeyIdentity(); String property = poll.getProperty(); log.info("===================Thread id>>" + Thread.currentThread().getId()); Long adminId = Long.valueOf(keyIdentity); Manager admin = managerService.getObjectById(adminId); OperationLog operationLog = new OperationLog(); operationLog.setAdmin(admin.getName()); System.out.println("==============operation>>" + property); operationLog.setOperation(property); operationLog.setCreateBy(adminId); operationLog.setUpdateBy(adminId); logs.add(operationLog); } catch (Exception e) { e.printStackTrace(); } } }); } if (logs.size() != 0) { try { log.info("==================insert database>>"); operationLogService.insertList(logs); } catch (Exception e) { e.printStackTrace(); } } } } // @Scheduled(cron = "0/30 * * * * ? * ") // public void timer() { // commitLogPool(); // } ``` 异常如下 ![图片说明](https://img-ask.csdn.net/upload/201710/11/1507704485_150283.png)
synchronized 加锁Integer对象后,多线程还是会得到相同的数据
``` public class ThreadDemo implements Runnable { public static volatile Integer a = 0; @Override public void run() { try { while (a < 1000) { synchronized (a) { a++; System.out.println(Thread.currentThread() + ":"+ a); } } }catch (Exception e){} } } ``` ![图片说明](https://img-ask.csdn.net/upload/201805/18/1526632565_425937.jpg)
多线程下Singleton模式
``` //singleton.h #ifndef _SINGLETON_H_ #define _SINGLETON_H_ #include "synobj.h" template<typename T> class Singleton { public: static T* Instance(); protected: private: Singleton(); ~Singleton(); Singleton(Singleton& ); Singleton& operator = (Singleton& ); static void Destory(); private: static T* _instance; static Mutex _mutex; }; ``` ``` //singleton.cpp //volatile的作用是: 作为指令关键字,确保本条指令不会因编译器的优化而省略,且要求每次直接读值. #include "stdafx.h" #include "singleton.h" #include <iostream> #include <stdlib.h> using namespace std; template<typename T> T* Singleton<T>::_instance = NULL; template<typename T> Mutex Singleton<T>::_mutex; template<typename T> Singleton<T>::Singleton() { } template<typename T> Singleton<T>::~Singleton() { } template<typename T> T* Singleton<T>::Instance() { if(_instance == NULL ) { Lock lock(_mutex); if(_instance == NULL) { T* temp = new T; _instance = temp; //_instance = new T(); atexit(Destory); } } return _instance; } template<typename T> void Singleton<T>::Destory() { if(NULL != _instance) { delete _instance; _instance = NULL; } } ``` ``` // Singleton20.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include "singleton.h" #include "synobj.h" #include <stdio.h> #include <iostream> using namespace std; class A:public Singleton<A> { public: void DoSomething() { cout<<"hello DoSomething"<<endl; } }; int _tmain(int argc, _TCHAR* argv[]) { A* a = A::Instance(); a->DoSomething(); getchar(); return 0; } ``` ![图片说明](https://img-ask.csdn.net/upload/201507/21/1437490284_73709.png) 我的代码大致是这样的,各位前辈们,帮忙分析一下我的错误吧。。。。
Java多线程并发问题。
``` public class Test { public static void main(String[] args) throws Exception { Executor executor = new Executor(); new Thread(executor::write).start(); new Thread(executor::read).start(); Thread.sleep(500000); } static class Executor { private int MAX_TIMES = 10000; private boolean hasValue = false; void write() { for (int i = 0; i < MAX_TIMES; i++) { while (hasValue) {} System.out.println("Write, " + i); hasValue = true; } } void read() { for (int i = 0; i < MAX_TIMES; i++) { while (!hasValue) {} hasValue = false; System.out.println("Read, " + i); } } } } ``` 我有这么一段代码,原本目的是两个线程交换执行、write线程执行一次,read线程执行一次,但hasValue并不是volatile类型,所以会发生死锁 我有两个问题: 1. 如果读写都是cache line,那为什么不是刚执行就发生死锁,而是执行一会,大概会交替执行100次左右才死锁。 2. 输出结果很奇怪,为什么不是write 0=> read 0 => write 1=>read 1.......这样下去,实际输出结果是这样的 ``` Write, 0 Write, 1 Read, 0 Read, 1 Write, 2 Read, 2 Write, 3 Write, 4 Read, 3 Read, 4 Write, 5 Write, 6 Read, 5 Read, 6 Write, 7 Write, 8 Read, 7 Read, 8 Write, 9 Write, 10 Read, 9 Read, 10 Write, 11 Write, 12 ```
求助,java多线程的问题,synchronized关键字不起作用
public class VoTest { private int num=1; private void increase(){ ** synchronized (this){ this.num++; }** } private int read(){ return this.num; } public static void main(String[] args) { final VoTest test=new VoTest(); for (int i = 0; i < 500; i++) { new Thread(new Runnable() { @Override public void run() { test.increase(); } }).start(); } //如果还有子线程在运行,主线程就主动让出cpu资源 //直到所有的子线程都运行结束 if(Thread.activeCount()>1){ Thread.yield(); } System.out.println("num="+test.read()); } } 按理说,synchronized关键字可以保证原子性和可见性,但是 这段代码的结果本应该是500,结果却千奇百怪,不管num加不加volatile关键字 都一样。 结果随便截了几个,求大神解答! ![第一次运行结果](https://img-ask.csdn.net/upload/201601/02/1451747367_172139.png) ![第二次运行结果](https://img-ask.csdn.net/upload/201601/02/1451747376_453608.png)
谁能真正整明白java volatile 关键字? 一知半解的莫入!
[code="java"] /** * VolatileTest.java * * Copyright ekupeng,Inc. 2012 */ package test; /** * @ClassName: VolatileTest * @Description: Volatile测试 * @author Emerson emsn1026@gmail.com * @date 2012-11-29 下午06:57:44 * @version V1.0 * */ public class VolatileTest extends Thread { // 非volatile标志 private static boolean flag1 = false; // volatile标志 private static volatile boolean flag2 = false; private int i = 0; public void run() { //Object o = new Object(); //synchronized (o) { /* * 注释1 */ while (!flag1) { i++; //注意 : System.out.println(i); /* * 注释2 */ if (flag2) { System.out.println("over:" + i); break; } } //} } public static void main(String[] args) { VolatileTest t = new VolatileTest(); t.start(); try { Thread.currentThread().sleep(2000); // 先更改flag1 t.flag1 = true; /* * 注释3 */ Thread.currentThread().sleep(1000); // 将flag2置为true,如果有机会进入if(flag2),则将退出循环 t.flag2 = true; } catch (InterruptedException e) { e.printStackTrace(); } } } [/code] 因为预览时发现大段的注释会自动换行,影响阅读代码,所以我将代码中的注释提取出来: 注释1 外围标志flag1为非volatile,该线程(t)跑起来后由另一线程(main)将flag1改为true后,如果出现情况1.flag1如果不从主存重新读取,那他将继续以false运行,所以会继续循环并进入内部的flag2的if判断;如果出现情况2.flag1从主存重新读取,那他将以true运行,所以会跳出循环,也就没有机会进入flag2的if判断了; 注释2 如果出现情况1,将进入该判断,内部标志flag2为volatile,当线程(main)将flag2改为true后,因为flag2会从主存重新读取,将以true运行,所以将跳出循环,并打印"over"语句 注释3 为了确保flag1的变更有机会被t察觉,并保证flag2能在flag1变为true后进行一次以上while(!flag1)条件判断后再判断if(flag2),sleep1秒(1秒可以跑很多循环了) 以上是我为了说明volatile的功能写的一段程序,目的是想说一个线程1在循环中通过非volatile的布尔变量来进行条件判断,即使在另一个线程2中修改了该布尔变量,由于该线程1的代码执行得到了某种性能优化,不会从主存重新读取布尔值,导致进入死循环,直到内部的volatile布尔值被改变才跳出。 我的问题是:原本我以为会像预想那样的输出“over”语句,这样也说明了volatile的用处。但是我尝试了Sun JDK1.6,1.5,1.4,1.3,1.2(因为volatile是针对jit带来的优化,所以1.2之前的版本就没有尝试)之后发现只有1.2下才会看到该程序对于volatile的演示效果,输出了“over”语句。其他的都只是在外围的while(!flag1)中实时察觉flag1的变化并跳出了循环。原本以为是hotspot的问题,但是我尝试了hotspot的server或client,以及1.3的classic,都是没有效果的,只有1.2才能看到volatile的演示效果。哪位大神给细说下这个情况? ps:Object那把锁没有实质的意义,只是进出synchronized块时会重新从主存同步数据,我当时随手写了测了下,所以大家可以不考虑,我暂且将它注掉吧....为了说明这一点,我加了行代码: //注意 : System.out.println(i); 这行代码要是去掉注释,volatile在JDK1.2下也将失去作用,因为System.out.println中含有同步块,一执行该方法,变量将从主存中重新读取。
求多线程调度问题调试
<div class="iteye-blog-content-contain" style="font-size: 14px;"> <p>目标是建立三个线程 th1,th2,th3,希望其能按照顺序th1-&gt;th2-&gt;th3的顺序执行。</p> <p>下面贴出我的代码,运行时总是不能得到正确的结果,求大神指点~~~~</p> <pre name="code" class="java">package threadSeq; public class testThSeq { public volatile static int state = 1; /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub Thread th1 = new Thread(new Runnable() { public void run() { try { increaseAndNotifyAll(1); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }); Thread th2 = new Thread(new Runnable() { public void run() { try { increaseAndNotifyAll(2); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }); Thread th3 = new Thread(new Runnable() { public void run() { try { increaseAndNotifyAll(3); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }); th3.start(); th2.start(); th1.start(); } public synchronized static void increaseAndNotifyAll(int wantedState) throws InterruptedException { System.out.println("state:"+state+";"+Thread.currentThread()+wantedState); while(state!=wantedState){ Thread.currentThread().wait(); Thread.currentThread().notifyAll(); } System.out.println(Thread.currentThread() + " finished"); state++; } }</pre> <p> </p> </div>
ConcurrentHashMap( since 1.5 jdk1.8)
有几点疑问想要请教大家,不吝赐教: 1.get方法的弱一致性: get方法并没有加锁,因此也不会和put方法冲突,当多个线程同时操作该map时,有的线程get,有的线程put,因为我们并不确定put方法执行完了没(即是否写了内存),所以get不一定能够得到最新值(put还没写进去,叫最新值也不是很妥当)。但是,一旦put操作执行完,那么get一定可以感知到最新值,因为: ``` static class Node<K,V> implements Map.Entry<K,V> { final int hash; final K key; **volatile** V val; **volatile** Node<K,V> next; ``` 2.size方法,也是没有加锁,存在和get方法同样的问题。
notifyAll方法只会通知wait状态的线程吗
** 功能:四个线程交替打印输出 问题:开始运行后如果两个线程B(backupB1,backupB2)都进入wait状态后,一个线程A(backupA1)获得锁并执行完毕后进行nofityAll操作,如果通知的是另一个线程A 那么不是另外两个线程B会一直wait下去? 所以想问下notifyAll方法只会通知wait状态的线程还是会连等待进入同步代码块的线程一起通知。即wait状态的线程和等待进入同步代码块的线程进行锁竞争** # 功能代码类 public class DBTools { volatile private boolean prevIsA = false; synchronized public void backupA() { try { while (prevIsA == true) { wait(); } for (int i = 0; i < 5; i++) { System.out.println("☆☆☆☆☆"); } prevIsA = true; notifyAll(); } catch (InterruptedException e) { e.printStackTrace(); } } synchronized public void backupB() { try { while (prevIsA == false) { wait(); } for (int i = 0; i < 5; i++) { System.out.println("△△△△△"); } prevIsA = false; notifyAll(); } catch (InterruptedException e) { e.printStackTrace(); } } } # 线程A public class BackupA extends Thread{ private DBTools dbTools; public BackupA(DBTools dbTools) { super(); this.dbTools = dbTools; } @Override public void run() { dbTools.backupA(); } } # 线程B public class BackupB extends Thread{ private DBTools dbTools; public BackupB(DBTools dbTools) { super(); this.dbTools = dbTools; } @Override public void run() { dbTools.backupB(); } } # 测试类 public class RunBackup { public static void main(String[] args) { DBTools dbTools = new DBTools(); BackupB backupB1 = new BackupB(dbTools); backupB1.start(); BackupB backupB2 = new BackupB(dbTools); backupB2.start(); try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } BackupA backupA1 = new BackupA(dbTools); backupA1.start(); BackupA backupA2 = new BackupA(dbTools); backupA2.start(); } }
java线程停止whlie里面的if语句,一会可以执行,一会不可以执行
我将if条件的times设置成大于等于二,但是一般要多执行几次才会执行出show,经常不会执行show,这是怎么回事啊? public class TestBank { public static void main(String[] args) { new TestBank().run(); } public void run() { Family f = new Family(); new Thread(f,"丈夫").start(); new Thread(f,"妻子").start(); while(true){ if(f.times>=2) { f.show(); break; } } } class Family implements Runnable { private int saveMoney; private int getMoney; private int curMoney; private volatile int times = 0; public Family() { saveMoney = 5000; getMoney = 2000; curMoney = 0; } @Override public void run() { System.out.println(Thread.currentThread().getName()+"取了:"+getMoney+"元"); curMoney+=getMoney; int temp = saveMoney - getMoney; try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } saveMoney = temp; times++; } public void show() { System.out.println("银行还有:"+saveMoney+",家里中有:"+curMoney); } } }
终于明白阿里百度这样的大公司,为什么面试经常拿ThreadLocal考验求职者了
点击上面↑「爱开发」关注我们每晚10点,捕获技术思考和创业资源洞察什么是ThreadLocalThreadLocal是一个本地线程副本变量工具类,各个线程都拥有一份线程私有的数
《奇巧淫技》系列-python!!每天早上八点自动发送天气预报邮件到QQ邮箱
此博客仅为我业余记录文章所用,发布到此,仅供网友阅读参考,如有侵权,请通知我,我会删掉。 补充 有不少读者留言说本文章没有用,因为天气预报直接打开手机就可以收到了,为何要多此一举发送到邮箱呢!!!那我在这里只能说:因为你没用,所以你没用!!! 这里主要介绍的是思路,不是天气预报!不是天气预报!!不是天气预报!!!天气预报只是用于举例。请各位不要再刚了!!! 下面是我会用到的两个场景: 每日下
面试官问我:什么是消息队列?什么场景需要他?用了会出现什么问题?
你知道的越多,你不知道的越多 点赞再看,养成习惯 GitHub上已经开源 https://github.com/JavaFamily 有一线大厂面试点脑图、个人联系方式,欢迎Star和完善 前言 消息队列在互联网技术存储方面使用如此广泛,几乎所有的后端技术面试官都要在消息队列的使用和原理方面对小伙伴们进行360°的刁难。 作为一个在互联网公司面一次拿一次Offer的面霸,打败了无数
8年经验面试官详解 Java 面试秘诀
    作者 | 胡书敏 责编 | 刘静 出品 | CSDN(ID:CSDNnews) 本人目前在一家知名外企担任架构师,而且最近八年来,在多家外企和互联网公司担任Java技术面试官,前后累计面试了有两三百位候选人。在本文里,就将结合本人的面试经验,针对Java初学者、Java初级开发和Java开发,给出若干准备简历和准备面试的建议。   Java程序员准备和投递简历的实
究竟你适不适合买Mac?
我清晰的记得,刚买的macbook pro回到家,开机后第一件事情,就是上了淘宝网,花了500元钱,找了一个上门维修电脑的师傅,上门给我装了一个windows系统。。。。。。 表砍我。。。 当时买mac的初衷,只是想要个固态硬盘的笔记本,用来运行一些复杂的扑克软件。而看了当时所有的SSD笔记本后,最终决定,还是买个好(xiong)看(da)的。 已经有好几个朋友问我mba怎么样了,所以今天尽量客观
MyBatis研习录(01)——MyBatis概述与入门
C语言自学完备手册(33篇) Android多分辨率适配框架 JavaWeb核心技术系列教程 HTML5前端开发实战系列教程 MySQL数据库实操教程(35篇图文版) 推翻自己和过往——自定义View系列教程(10篇) 走出思维困境,踏上精进之路——Android开发进阶精华录 讲给Android程序员看的前端系列教程(40集免费视频教程+源码) 版权声明 本文原创作者:谷哥的小弟 作者博客
程序员一般通过什么途径接私活?
二哥,你好,我想知道一般程序猿都如何接私活,我也想接,能告诉我一些方法吗? 上面是一个读者“烦不烦”问我的一个问题。其实不止是“烦不烦”,还有很多读者问过我类似这样的问题。 我接的私活不算多,挣到的钱也没有多少,加起来不到 20W。说实话,这个数目说出来我是有点心虚的,毕竟太少了,大家轻喷。但我想,恰好配得上“一般程序员”这个称号啊。毕竟苍蝇再小也是肉,我也算是有经验的人了。 唾弃接私活、做外
Python爬虫爬取淘宝,京东商品信息
小编是一个理科生,不善长说一些废话。简单介绍下原理然后直接上代码。 使用的工具(Python+pycharm2019.3+selenium+xpath+chromedriver)其中要使用pycharm也可以私聊我selenium是一个框架可以通过pip下载 pip install selenium -i https://pypi.tuna.tsinghua.edu.cn/simple/ 
阿里程序员写了一个新手都写不出的低级bug,被骂惨了。
你知道的越多,你不知道的越多 点赞再看,养成习惯 本文 GitHub https://github.com/JavaFamily 已收录,有一线大厂面试点思维导图,也整理了很多我的文档,欢迎Star和完善,大家面试可以参照考点复习,希望我们一起有点东西。 前前言 为啥今天有个前前言呢? 因为你们的丙丙啊,昨天有牌面了哟,直接被微信官方推荐,知乎推荐,也就仅仅是还行吧(心里乐开花)
Java工作4年来应聘要16K最后没要,细节如下。。。
前奏: 今天2B哥和大家分享一位前几天面试的一位应聘者,工作4年26岁,统招本科。 以下就是他的简历和面试情况。 基本情况: 专业技能: 1、&nbsp;熟悉Sping了解SpringMVC、SpringBoot、Mybatis等框架、了解SpringCloud微服务 2、&nbsp;熟悉常用项目管理工具:SVN、GIT、MAVEN、Jenkins 3、&nbsp;熟悉Nginx、tomca
Python爬虫精简步骤1 获取数据
爬虫的工作分为四步: 1.获取数据。爬虫程序会根据我们提供的网址,向服务器发起请求,然后返回数据。 2.解析数据。爬虫程序会把服务器返回的数据解析成我们能读懂的格式。 3.提取数据。爬虫程序再从中提取出我们需要的数据。 4.储存数据。爬虫程序把这些有用的数据保存起来,便于你日后的使用和分析。 这一篇的内容就是:获取数据。 首先,我们将会利用一个强大的库——requests来获取数据。 在电脑上安装
Python绘图,圣诞树,花,爱心 | Turtle篇
1.画圣诞树 import turtle screen = turtle.Screen() screen.setup(800,600) circle = turtle.Turtle() circle.shape('circle') circle.color('red') circle.speed('fastest') circle.up() square = turtle.Turtle()
作为一个程序员,CPU的这些硬核知识你必须会!
CPU对每个程序员来说,是个既熟悉又陌生的东西? 如果你只知道CPU是中央处理器的话,那可能对你并没有什么用,那么作为程序员的我们,必须要搞懂的就是CPU这家伙是如何运行的,尤其要搞懂它里面的寄存器是怎么一回事,因为这将让你从底层明白程序的运行机制。 随我一起,来好好认识下CPU这货吧 把CPU掰开来看 对于CPU来说,我们首先就要搞明白它是怎么回事,也就是它的内部构造,当然,CPU那么牛的一个东
破14亿,Python分析我国存在哪些人口危机!
2020年1月17日,国家统计局发布了2019年国民经济报告,报告中指出我国人口突破14亿。 猪哥的朋友圈被14亿人口刷屏,但是很多人并没有看到我国复杂的人口问题:老龄化、男女比例失衡、生育率下降、人口红利下降等。 今天我们就来分析一下我们国家的人口数据吧! 更多有趣分析教程,扫描下方二维码关注vx公号「裸睡的猪」 即可查看! 一、背景 1.人口突破14亿 2020年1月17日,国家统计局发布
web前端javascript+jquery知识点总结
Javascript javascript 在前端网页中占有非常重要的地位,可以用于验证表单,制作特效等功能,它是一种描述语言,也是一种基于对象(Object)和事件驱动并具有安全性的脚本语言 ,语法同java类似,是一种解释性语言,边执行边解释。 JavaScript的组成: ECMAScipt 用于描述: 语法,变量和数据类型,运算符,逻辑控制语句,关键字保留字,对象。 浏览器对象模型(Br
Python实战:抓肺炎疫情实时数据,画2019-nCoV疫情地图
文章目录1. 前言2. 数据下载3. 数据处理4. 数据可视化 1. 前言 今天,群里白垩老师问如何用python画武汉肺炎疫情地图。白垩老师是研究海洋生态与地球生物的学者,国家重点实验室成员,于不惑之年学习python,实为我等学习楷模。先前我并没有关注武汉肺炎的具体数据,也没有画过类似的数据分布图。于是就拿了两个小时,专门研究了一下,遂成此文。 2月6日追记:本文发布后,腾讯的数据源多次变更u
听说想当黑客的都玩过这个Monyer游戏(1~14攻略)
第零关 进入传送门开始第0关(游戏链接) 请点击链接进入第1关: 连接在左边→ ←连接在右边 看不到啊。。。。(只能看到一堆大佬做完的留名,也能看到菜鸡的我,在后面~~) 直接fn+f12吧 &lt;span&gt;连接在左边→&lt;/span&gt; &lt;a href="first.php"&gt;&lt;/a&gt; &lt;span&gt;←连接在右边&lt;/span&gt; o
在家远程办公效率低?那你一定要收好这个「在家办公」神器!
相信大家都已经收到国务院延长春节假期的消息,接下来,在家远程办公可能将会持续一段时间。 但是问题来了。远程办公不是人在电脑前就当坐班了,相反,对于沟通效率,文件协作,以及信息安全都有着极高的要求。有着非常多的挑战,比如: 1在异地互相不见面的会议上,如何提高沟通效率? 2文件之间的来往反馈如何做到及时性?如何保证信息安全? 3如何规划安排每天工作,以及如何进行成果验收? ......
作为一个程序员,内存和磁盘的这些事情,你不得不知道啊!!!
截止目前,我已经分享了如下几篇文章: 一个程序在计算机中是如何运行的?超级干货!!! 作为一个程序员,CPU的这些硬核知识你必须会! 作为一个程序员,内存的这些硬核知识你必须懂! 这些知识可以说是我们之前都不太重视的基础知识,可能大家在上大学的时候都学习过了,但是嘞,当时由于老师讲解的没那么有趣,又加上这些知识本身就比较枯燥,所以嘞,大家当初几乎等于没学。 再说啦,学习这些,也看不出来有什么用啊!
渗透测试-灰鸽子远控木马
木马概述 灰鸽子( Huigezi),原本该软件适用于公司和家庭管理,其功能十分强大,不但能监视摄像头、键盘记录、监控桌面、文件操作等。还提供了黑客专用功能,如:伪装系统图标、随意更换启动项名称和表述、随意更换端口、运行后自删除、毫无提示安装等,并采用反弹链接这种缺陷设计,使得使用者拥有最高权限,一经破解即无法控制。最终导致被黑客恶意使用。原作者的灰鸽子被定义为是一款集多种控制方式于一体的木马程序
Python:爬取疫情每日数据
前言 有部分同学留言说为什么412,这是因为我代码里全国的cookies需要你自己打开浏览器更新好后替换,而且这个cookies大概只能持续20秒左右! 另外全国卫健委的数据格式一直在变,也有可能会导致爬取失败! 我现在已根据2月14日最新通报稿的格式修正了! 目前每天各大平台,如腾讯、今日头条都会更新疫情每日数据,他们的数据源都是一样的,主要都是通过各地的卫健委官网通报。 为什么已经有大量平台做
这个世界上人真的分三六九等,你信吗?
偶然间,在知乎上看到一个问题 一时间,勾起了我深深的回忆。 以前在厂里打过两次工,做过家教,干过辅导班,做过中介。零下几度的晚上,贴过广告,满脸、满手地长冻疮。   再回首那段岁月,虽然苦,但让我学会了坚持和忍耐。让我明白了,在这个世界上,无论环境多么的恶劣,只要心存希望,星星之火,亦可燎原。   下文是原回答,希望能对你能有所启发。   如果我说,这个世界上人真的分三六九等,
B 站上有哪些很好的学习资源?
哇说起B站,在小九眼里就是宝藏般的存在,放年假宅在家时一天刷6、7个小时不在话下,更别提今年的跨年晚会,我简直是跪着看完的!! 最早大家聚在在B站是为了追番,再后来我在上面刷欧美新歌和漂亮小姐姐的舞蹈视频,最近两年我和周围的朋友们已经把B站当作学习教室了,而且学习成本还免费,真是个励志的好平台ヽ(.◕ฺˇд ˇ◕ฺ;)ノ 下面我们就来盘点一下B站上优质的学习资源: 综合类 Oeasy: 综合
雷火神山直播超两亿,Web播放器事件监听是怎么实现的?
Web播放器解决了在手机浏览器和PC浏览器上播放音视频数据的问题,让视音频内容可以不依赖用户安装App,就能进行播放以及在社交平台进行传播。在视频业务大数据平台中,播放数据的统计分析非常重要,所以Web播放器在使用过程中,需要对其内部的数据进行收集并上报至服务端,此时,就需要对发生在其内部的一些播放行为进行事件监听。 那么Web播放器事件监听是怎么实现的呢? 01 监听事件明细表 名
3万字总结,Mysql优化之精髓
本文知识点较多,篇幅较长,请耐心学习 MySQL已经成为时下关系型数据库产品的中坚力量,备受互联网大厂的青睐,出门面试想进BAT,想拿高工资,不会点MySQL优化知识,拿offer的成功率会大大下降。 为什么要优化 系统的吞吐量瓶颈往往出现在数据库的访问速度上 随着应用程序的运行,数据库的中的数据会越来越多,处理时间会相应变慢 数据是存放在磁盘上的,读写速度无法和内存相比 如何优化 设计
Python新型冠状病毒疫情数据自动爬取+统计+发送报告+数据屏幕(三)发送篇
今天介绍的项目是使用 Itchat 发送统计报告 项目功能设计: 定时爬取疫情数据存入Mysql 进行数据分析制作疫情报告 使用itchat给亲人朋友发送分析报告(本文) 基于Django做数据屏幕 使用Tableau做数据分析 来看看最终效果 目前已经完成,预计2月12日前更新 使用 itchat 发送数据统计报告 itchat 是一个基于 web微信的一个框架,但微信官方并不允
作为程序员的我,大学四年一直自学,全靠这些实用工具和学习网站!
我本人因为高中沉迷于爱情,导致学业荒废,后来高考,毫无疑问进入了一所普普通通的大学,实在惭愧...... 我又是那么好强,现在学历不行,没办法改变的事情了,所以,进入大学开始,我就下定决心,一定要让自己掌握更多的技能,尤其选择了计算机这个行业,一定要多学习技术。 在进入大学学习不久后,我就认清了一个现实:我这个大学的整体教学质量和学习风气,真的一言难尽,懂的人自然知道怎么回事? 怎么办?我该如何更好的提升
粒子群算法求解物流配送路线问题(python)
粒子群算法求解物流配送路线问题(python) 1.查找论文文献 找一篇物流配送路径优化+粒子群算法求解的论文 参考文献:基于混沌粒子群算法的物流配送路径优化 2.了解粒子群算法的原理 讲解通俗易懂,有数学实例的博文:https://blog.csdn.net/daaikuaichuan/article/details/81382794 3.确定编码方式和解码策略 3.1编码方式 物流配送路线的
教你如何编写第一个简单的爬虫
很多人知道爬虫,也很想利用爬虫去爬取自己想要的数据,那么爬虫到底怎么用呢?今天就教大家编写一个简单的爬虫。 下面以爬取笔者的个人博客网站为例获取第一篇文章的标题名称,教大家学会一个简单的爬虫。 第一步:获取页面 #!/usr/bin/python # coding: utf-8 import requests #引入包requests link = "http://www.santostang.
前端JS初级面试题二 (。•ˇ‸ˇ•。)老铁们!快来瞧瞧自己都会了么
1. 传统事件绑定和符合W3C标准的事件绑定有什么区别? 传统事件绑定 &lt;div onclick=""&gt;123&lt;/div&gt; div1.onclick = function(){}; &lt;button onmouseover=""&gt;&lt;/button&gt; 注意: 如果给同一个元素绑定了两次或多次相同类型的事件,那么后面的绑定会覆盖前面的绑定 (不支持DOM事...
相关热词 c# 压缩图片好麻烦 c#计算数组中的平均值 c#获取路由参数 c#日期精确到分钟 c#自定义异常必须继承 c#查表并返回值 c# 动态 表达式树 c# 监控方法耗时 c# listbox c#chart显示滚动条
立即提问