当前位置: 首页 > news >正文

重庆塔吊证查询网站个人网站命名技巧

重庆塔吊证查询网站,个人网站命名技巧,中国建筑招聘信息,医疗网站怎么做优化面试多线程八股文十问十答第一期 作者#xff1a;程序员小白条#xff0c;个人博客 相信看了本文后#xff0c;对你的面试是有一定帮助的#xff01; ⭐点赞⭐收藏⭐不迷路#xff01;⭐ 1.ThreadLocal如何实现线程安全 Java的ThreadLocal是一个线程本地变量#xff0…面试多线程八股文十问十答第一期 作者程序员小白条个人博客 相信看了本文后对你的面试是有一定帮助的 ⭐点赞⭐收藏⭐不迷路⭐ 1.ThreadLocal如何实现线程安全 Java的ThreadLocal是一个线程本地变量它提供了一种简单的机制来实现线程封闭Thread confinement。ThreadLocal为每个线程提供了一个独立的副本每个线程都可以访问自己的副本从而避免了线程安全问题。ThreadLocal实现线程安全的核心是每个线程都有自己的变量副本每个线程访问的都是自己的变量副本从而避免了多线程之间的竞争和冲突。当多个线程共享同一个对象时如果没有采取线程安全的措施就会出现多个线程同时修改同一个对象的情况从而导致数据不一致或者出现异常。ThreadLocal的作用实现线程范围内的局部变量即ThreadLocal在一个线程中是共享的在不同线程之间是隔离的。 在Java中使用ThreadLocal实现线程安全的具体步骤如下 在类中创建ThreadLocal变量每个线程都可以访问这个变量的副本。在需要访问共享变量的方法中通过ThreadLocal.get()方法获取当前线程的变量副本。如果当前线程没有创建过变量副本那么就通过ThreadLocal.set()方法创建一个变量副本。在方法执行结束时通过ThreadLocal.remove()方法删除当前线程的变量副本。 通过ThreadLocal实现线程安全的好处是可以简化线程安全的处理过程避免了显式的同步操作提高了代码的可读性和可维护性。但是需要注意的是ThreadLocal只能保证线程内部的线程安全无法保证多个线程之间的线程安全。在多线程环境下仍然需要采取其他措施来保证多个线程之间的数据同步和一致性。也就是说每个线程访问的是自己独立的变量副本但是多个线程之间共享的数据还是存在竞争和冲突的可能性。如果需要保证多个线程之间的数据同步和一致性仍然需要采取其他措施例如使用synchronized关键字或者使用锁机制等。因此需要根据实际的业务场景和需求来选择合适的线程安全措施不能仅仅依靠ThreadLocal来实现线程安全。 2.子线程如何获得父线程的ThreadLocal 在Java中子线程无法直接访问父线程的ThreadLocal变量因为ThreadLocal是线程封闭的每个线程都拥有自己独立的变量副本。 但是如果在创建子线程时将父线程的ThreadLocal变量传递给子线程子线程就可以访问父线程的ThreadLocal变量了。具体实现方法如下 1.在父线程中创建并初始化ThreadLocal变量。 2.在创建子线程时将父线程的ThreadLocal变量作为参数传递给子线程。 3.在子线程中通过参数获取父线程的ThreadLocal变量并使用该变量。 public class ParentThread {// 创建父线程的ThreadLocal变量public static ThreadLocalString threadLocal new ThreadLocalString();public static void main(String[] args) {// 设置父线程的ThreadLocal变量threadLocal.set(Hello World!);// 创建子线程并将父线程的ThreadLocal变量传递给子线程Thread childThread new Thread(new ChildThread(threadLocal.get()));childThread.start();} }class ChildThread implements Runnable {private String value;public ChildThread(String value) {this.value value;}public void run() {// 在子线程中获取父线程的ThreadLocal变量String parentValue this.value;System.out.println(Parent Thread Local Value: parentValue);} }3.线程能同时访问类中的两个Synchronized的同步方法吗?这两个同步方法能互相访问吗? 线程可以同时访问类中的两个Synchronized的同步方法但是这两个同步方法不能互相访问。Synchronized关键字可以保证同一时间只有一个线程进入同步代码块或同步方法如果一个线程进入了一个Synchronized方法或代码块其他线程就必须等待该线程执行完毕才能进入该方法或代码块。但是如果一个线程已经获得了一个Synchronized方法或代码块的锁它就可以同时访问另一个Synchronized方法或代码块因为这两个方法使用的是不同的锁。也就是说如果类中有两个Synchronized方法这两个方法使用的锁是不同的因此不会相互影响线程可以同时访问它们。然而如果一个Synchronized方法或代码块在执行过程中调用了另一个Synchronized方法或代码块就会出现锁竞争(在锁一样的情况下的问题即第一个Synchronized方法或代码块已经获得了锁但是第二个Synchronized方法或代码块也需要获得同样的锁才能执行因此第二个Synchronized方法或代码块就会被阻塞。如果第一个Synchronized方法或代码块等待第二个Synchronized方法或代码块执行完毕才能继续执行就会出现死锁的情况。因此两个Synchronized方法或代码块不能互相访问否则会出现锁竞争和死锁问题。 4.sleep()和wait()方法的作用 线程sleep 和wait 的区别 1、这两个方法来自不同的类分别是Thread和Object 2、最主要是sleep方法没有释放锁而wait方法释放了锁使得其他线程可以使用同步控制块或者方法。 3、waitnotify和notifyAll只能在同步控制方法或者同步控制块里面使用而sleep可以在任何地方使用使用范围 4、sleep必须捕获异常wait必须捕获异常之前看到网上很多博客都说wait方法不需要抛出异常这个观点是错误的千万不要被误导了notify和notifyAll方法确实可以不用抛出异常 不加抛异常处理的会编译通不过 sleep是Thread类的静态方法。sleep的作用是让线程休眠制定的时间在时间到达时恢复也就是说sleep将在接到时间到达事件事恢复线程执行。wait是Object的方法也就是说可以对任意一个对象调用wait方法调用wait方法将会将调用者的线程挂起直到其他线程调用同一个对象的notify方法才会重新激活调用者。 共同点 它们都可以被interrupted方法中断。 Thread.Sleep(1000) 意思是在未来的1000毫秒内本线程不参与CPU竞争1000毫秒过去之后这时候也许另外一个线程正在使用CPU那么这时候操作系统是不会重新分配CPU的直到那个线程挂起或结束即使这个时候恰巧轮到操作系统进行CPU 分配那么当前线程也不一定就是总优先级最高的那个CPU还是可能被其他线程抢占去。另外值得一提的是Thread.Sleep(0)的作用就是触发操作系统立刻重新进行一次CPU竞争竞争的结果也许是当前线程仍然获得CPU控制权也许会换成别的线程获得CPU控制权。 wait(1000)表示将锁释放1000毫秒到时间后如果锁没有被其他线程占用则再次得到锁然后wait方法结束执行后面的代码如果锁被其他线程占用则等待其他线程释放锁。注意设置了超时时间的wait方法一旦过了超时时间并不需要其他线程执行notify也能自动解除阻塞但是如果没设置超时时间的wait方法必须等待其他线程执行notify。sleep()方法导致了程序暂停执行指定的时间让出cpu该其他线程但是他的监控状态依然保持者当指定的时间到了又会自动恢复运行状态。 在调用sleep()方法的过程中线程不会释放对象锁。 而当调用wait()方法的时候线程会放弃对象锁进入等待此对象的等待锁定池只有针对此对象调用notify()方法后本线程才进入对象锁定池准备 sleep可以在任何地方使用而wait只能在同步方法或者同步块中使用。 5.Lock锁 synchronized是Java语言的关键字。Lock是一个接口。synchronized不需要用户去手动释放锁发生异常或者线程结束时自动释放锁;Lock则必须要用户去手动释放锁如果没有主动释放锁就有可能导致出现死锁现象。lock可以配置公平策略,实现线程按照先后顺序获取锁。提供了trylock方法 可以试图获取锁获取到或获取不到时返回不同的返回值 让程序可以灵活处理。lock()和unlock()可以在不同的方法中执行,可以实现同一个线程在上一个方法中lock()在后续的其他方法中unlock(),比syncronized灵活的多。 6.如何实现所有线程在某个线程发生了之后再执行 1.闭锁CountDownLatch闭锁是典型的等待事件发生的同步工具类将闭锁的初始值设置1所有线程调用await方法等待当事件发生时调用countDown将闭锁值减为0则所有await等待闭锁的线程得以继续执行。 2.阻塞队列BlockingQueue所有等待事件的线程尝试从空的阻塞队列获取元素将阻塞当事件发生时向阻塞队列中同时放入N个元素(N的值与等待的线程数相同)则所有等待的线程从阻塞队列中取出元素后得以继续执行。 3.信号量Semaphore设置信号量的初始值为等待的线程数N一开始将信号量申请完让剩余的信号量为0待事件发生时同时释放N个占用的信号量则等待信号量的所有线程将获取信号量得以继续执行。 4.栅栏CyclicBarrier设置栅栏的初始值为1当事件发生时调用barrier.wait()冲破设置的栅栏将调用指定的Runable线程执行在该线程中启动N个新的子线程执行。这个方法并不是让执行中的线程全部等待在某个点待某一事件发生后继续执行。 特别注意不能用“条件队列”多个线程阻塞等待在条件队列上事件发生时调用“条件队列”的notifyAll方法或者signalAll方法虽然能唤醒所有等待线程但是只有一个线程能够获得该条件队列的锁得以调度执行其它线程未获得锁仍将继续阻塞等待。 7.如何保证多线程下的i结果正确 1.使用 synchronized 关键字 public class MyThread implements Runnable { private int i;public MyThread(int i) { this.i i; }Override public void run() { synchronized (this) { System.out.println(i); } } }2.Atomic变量 使用AtomicInteger类来代替int类型可以保证原子性。AtomicInteger类提供了线程安全的原子操作方法如incrementAndGet()。 private AtomicInteger i new AtomicInteger(0);public void increment() {i.incrementAndGet(); }3.Lock对象 使用Lock对象来对共享变量进行同步保证同一时刻只有一个线程能够访问该变量。 private Lock lock new ReentrantLock();public void increment() {lock.lock();try {i;} finally {lock.unlock();} }4.ThreadLocal变量 使用ThreadLocal变量来对共享变量进行封装每个线程都拥有自己的副本可以保证线程安全。 private ThreadLocalInteger threadLocal new ThreadLocalInteger() {Overrideprotected Integer initialValue() {return 0;} };public void increment() {threadLocal.set(threadLocal.get() 1); }8.volatile是怎么知道多线程下数据变更的 volatile 关键字用于标记一个变量是 volatile 的这意味着这个变量的值可能会被多个线程同时修改因此需要及时更新到内存中以确保其他线程能够及时看到值的变化。 当一个线程访问一个 volatile 变量时Java 虚拟机会自动将该变量的值复制到线程本地内存中以便其他线程能够访问该变量的值。当一个线程修改了 volatile 变量的值后Java 虚拟机也会自动将修改后的值复制回线程本地内存中以便其他线程能够更新他们的本地内存。由于 volatile 变量的值会被及时更新到内存中因此其他线程可以及时看到该变量的值发生变化。如果一个变量不是 volatile 的那么其他线程只能读取该变量的先前值而不能直接读取最新的值因为这样需要从磁盘或者其他慢速存储介质中读取数据会降低程序的性能。需要注意的是虽然 volatile 能够确保多线程下数据变更的正确性但它并不能保证线程的安全性。如果在多线程环境下修改一个非 volatile 变量的值可能会引起竞态条件等问题因此需要谨慎使用 volatile 关键字。 9.线程池的执行流程和线程池的拒绝策略和核心配置参数 corePoolSize:核心线程数 maxiumPoolSize:最大线程数 keepAliveTime:空闲存活时间 unit: 时间单位 workQueue:任务队列 threadFactory: 线程工厂 handler:拒绝策略 线程池的执行流程有 3 个重要的判断点 判断当前线程数和核心线程数.判断当前任务队列是否已满.判断当前线程数是否已达最大线程数. 如果在经过上诉三个过程后, 得到的结果都是 true , 那么就会执行线程池的拒绝策略. 二. 拒绝策略当任务过多且线程池的任务队列已满时, 此时就会执行线程池的拒绝策略, 线程池的拒绝策略默认有以下 4 种: AbortPolicy中止策略线程池会抛出异常并中止执行此任务.CallerRunsPolicy调用方运行策略把任务交给添加此任务的main线程来执行.DiscardPolicy放弃最新策略忽略此任务忽略最新的一个任务.DiscardOldestPolicy放弃最旧策略忽略最早的任务最先加入队列的任务. AbortPolicy中止策略功能: 当触发拒绝策略时直接抛出拒绝执行的异常中止策略的意思也就是打断当前执行流程CallerRunsPolicy调用者运行策略功能当触发拒绝策略时只要线程池没有关闭就由提交任务的当前线程处理.DiscardPolicy丢弃策略功能直接静悄悄的丢弃这个任务不触发任何动作.DiscardOldestPolicy弃老策略功能如果线程池未关闭就弹出队列头部的元素然后尝试执行. 一般情况下任务分为IO密集型和CPU密集型。 CPU密集型一般设置为cpu核数1 IO密集型一般设置为2n以IO能力为主。 10.线程创建的几种方法 继承Thread实现Runnable接口实现Callable接口结合 FutureTask使用利用该线程池ExecutorService、Callable、Future来实现
http://www.hkea.cn/news/14418233/

相关文章:

  • 如何安装织梦做的网站海口网站seo
  • 广州网站快速制作seo学徒是做什么
  • 阜宁网站制作哪家好鄠邑区建设和住房保障局网站
  • 网站建设的关键点中国建筑建设通的网站
  • 地方网站有何作用建设银行交易明细查询网站
  • 想要做一个网站 该怎么做cc插件 wordpress
  • 常州网站建设段新浩网站用html模拟图片
  • 用腾讯云做网站泰钢材企业网站源码
  • 没经验怎么开广告公司营销网站seo推广费用
  • 网站链接用处如何将网站添加到域名
  • 网站后台 用什么编写泉州企业建站系统
  • 甘肃做网站哪家专业电商公司经营范围
  • 微信网站建设 知乎lol小米和谁做的视频网站
  • 网站升级改版方案上海展览设计制作公司
  • xampp做网站可以吗智慧团建网站什么时候维护好
  • 怎么做游戏和网站漏洞wordpress 5图片相对路径
  • 深圳营销型网站建设公司免费海报制作网站
  • 珠海网站建设报价哪些企业需要网站建设
  • 企业网站建设word全国建设工程造价管理系统
  • 官网网站页面设计网站开发技术方案与实施
  • 网站开发需要英语营销型网站建设的优缺点
  • 网站建设与什么专业有关android手机网站开发
  • 美区能和国区家庭共享吗sem和seo哪个工作好
  • 网站建设投标文件范本华为云免费服务器
  • 做视频网站把视频放在哪里找网站名怎么写
  • 如何设置网站公司动态中国核工业第五建设有限公司待遇
  • 网站开发工资咋样模板网站与定制网站区别
  • 做摄影网站的公司中国关键词官网
  • 辽宁省建设厅网站官网广州市网站建设 骏域
  • 摄影网站建设解决方案邓州微网站开发