jdk线程常见面试题
请编写一个多线程程序,实现两个线程,其中一个线程完成对某个对象int成员变量的增加操作,即每次加1,另一个线程完成对该对象成员变量的减操作,即每次减1,同时要保证该变量的值不会小于0,不会大于1,该变量的初始值为0。
class Sample {
private int number;
public synchronized void increase() {
while (0 != number) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
number++;
System.out.println(number);
this.notifyAll();
}
public synchronized void decrease() {
while (0 == number) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
number--;
System.out.println(number);
this.notifyAll();
}
}
class IncreaseThread implements Runnable {
private Sample sample;
public IncreaseThread(Sample sample) {
this.sample = sample;
}
@Override
public void run() {
for (int i = 0; i < 20; i++) {
try {
Thread.sleep((long)(Math.random() * 1000));
} catch (InterruptedException e) {
e.printStackTrace();
}
sample.increase();
}
}
}
class DecreaseThread implements Runnable {
private Sample sample;
public DecreaseThread(Sample sample) {
this.sample = sample;
}
@Override
public void run() {
for (int i = 0; i < 20; i++) {
try {
Thread.sleep((long)(Math.random() * 1000));
} catch (InterruptedException e) {
e.printStackTrace();
}
sample.decrease();
}
}
}
public class MainTest {
public static void main(String[] args) {
Sample sample = new Sample();
Runnable runnable1 = new IncreaseThread(sample);
Runnable runnable2 = new DecreaseThread(sample);
Thread thread1 = new Thread(runnable1);
Thread thread2 = new Thread(runnable2);
thread1.start();
thread2.start();
}
}
关于wait(),notify(),notifyAll()以及sleep()方法的关系
1)如果一个线程调用了某个对象的wait方法,那么该线程首先必须要拥有对象的锁(synchronized),换句话说,该wait方法必须出现在synchronized中;
2)如果一个线程调用了某个对象的wait方法,那么该线程就会释放该对象的锁;
3)在java对象中,有两种池(锁池和等待池);
4)如果一个线程调用了某个对象的wait方法,那么线程进入该对象的等待池(释放锁),如果未来某一时刻另一个线程调用了相同对象的notify/notifyAll方法,那么在该等待池中等待的线程就会起来进入该对象的锁池中,去等待获得该对象的锁,如果获得锁成功后,那么该线程将继续沿着wait方法之后的路径去执行;
5)Thread.sleep(long),如果一个线程调用了sleep方法睡眠,那么在睡眠的同时,不会丢失对象的锁的所有权;
6)wait、notify、notifyAll方法都是定义在Object类中的,而且是final的,因此会被所有的Java类所继承并且无法重写。这两个方法要求在调用时线程应该已经获得了对象的锁。这三个方法必须由同步监视对象/锁来调用,锁可以是任意的对象,任意的对象调用的方式一定定义在Object中;
7)notify方法是去等待池中随机的唤醒一个正在等待的线程,而notifyAll方法是唤醒所有等待池中的线程;
8)wait有个重载的方法public final void wait(long timeout),表示在指定的时候过了以后,线程自动进入等待池等待被调用;当指定的时间没有到的时候可以通过notify/notifyAll的方法唤醒;
9)wait():让当前线程放弃监视器进入等待,直到其他线程调用同一个监视器并调用notify()或notifyAll()为止;
notify():唤醒在同一对象监听器中调用wait方法的第一个线程;
notifyAll():唤醒在同一对象监听器中调用wait方法的所有线程。
10) wait可以指定时间也可以不指定时间;sleep必须指定时间;在同步中时,对CPU的执行权和锁的处理不同:wait释放执行权,释放锁;sleep释放执行权,不释放锁;
11) synchronized修饰的方法,因为该类的默认实例(this)是同步监视器,所有可以在同步方法中直接调用这三个方法;synchronized修饰的同步代码块,同步监视器是括号里的对象,所以必须使用该对象调用这三个方法;
12) 使用Lock对象来保证同步时,系统中不存在隐式的同步监视对象,那么就不能使用这三个方法了,那该怎么办呢?此时,Lock代替了同步方法/同步代码块,将同步的隐式锁变成显示锁操作,可以为一个锁加上多组监视器。Condition代替了同步监视器的功能。Condition对象通过Lock对象的newCondition()方法创建;
里面方法包括: await(): 等价于同步监听器的wait()方法;signal(): 等价于同步监听器的notify()方法; signalAll(): 等价于同步监听器的notifyAll()方法;
以前一个锁上只能有一组监视器方法。现在,一个Lock锁上可以多组监视器方法对象。可以实现一组负责生产者,一组负责消费者。
synchronized关键字的作用
1)在某个对象的所有synchronized方法中,在某一个时刻,只能有唯一的一个线程去访问这些synchronized方法;
2)如果一个方法是synchronized方法,那么该synchronized关键字给当前对象上锁(即this);
3)如果一个synchronized方法是static的,那么该synchronized关键字表示的是给当前对象所对应的Class对象上锁(每个类,不管生成多少对象,其对应的Class只有一个)。
jdk线程常见面试题的更多相关文章
- Java线程常见面试题
v 多线程实现手段: (1).继承Thread类 (2)实现Runable接口 (3)使用线程池 v 线程控制在那个包:java.util.concurrent. (1)提供了线程的运行.(2)线程池 ...
- java主线程等待所有子线程执行完毕在执行(常见面试题)
java主线程等待所有子线程执行完毕在执行(常见面试题) java主线程等待所有子线程执行完毕在执行,这个需求其实我们在工作中经常会用到,比如用户下单一个产品,后台会做一系列的处理,为了提高效率,每个 ...
- java常见面试题及答案 1-10(基础篇)
java常见面试题及答案 1.什么是Java虚拟机?为什么Java被称作是"平台无关的编程语言"? Java 虚拟机是一个可以执行 Java 字节码的虚拟机进程.Java 源文件被 ...
- java常见面试题及答案
java常见面试题及答案 来源 https://blog.csdn.net/hsk256/article/details/49052293 来源 https://blog.csdn.net/hsk25 ...
- Java 常见面试题(一)
1)什么是Java虚拟机?为什么Java被称作是“平台无关的编程语言”? Java虚拟机是一个可以执行Java字节码的虚拟机进程.Java源文件被编译成能被Java虚拟机执行的字节码文件.Java被设 ...
- 【搞定 Java 并发面试】面试最常问的 Java 并发进阶常见面试题总结!
本文为 SnailClimb 的原创,目前已经收录自我开源的 JavaGuide 中(61.5 k Star![Java学习+面试指南] 一份涵盖大部分Java程序员所需要掌握的核心知识.觉得内容不错 ...
- Spring 常见面试题总结 | JavaGuide
首发于 JavaGuide 在线网站:Spring 常见面试题总结 最近在对 JavaGuide 的内容进行重构完善,同步一下最新更新,希望能够帮助你. Spring 基础 什么是 Spring 框架 ...
- iOS常见面试题汇总
iOS常见面试题汇总 1. 什么是 ARC? (ARC 是为了解决什么问题而诞生的?) ARC 是 Automatic Reference Counting 的缩写, 即自动引用计数. 这是苹果在 i ...
- Mybatis常见面试题
Mybatis常见面试题 #{}和${}的区别是什么? #{}和${}的区别是什么? 在Mybatis中,有两种占位符 #{}解析传递进来的参数数据 ${}对传递进来的参数原样拼接在SQL中 #{}是 ...
随机推荐
- Hive(七):HQL DML
HQL DML 主要涉到对Hive表中数据操作,包含有:load.INSERT.DELETE.EXPORT and IMPORT,详细资料参见:https://cwiki.apache.org/con ...
- 每日学习心得:Js获取Checkboxlist所选值、instanceof 和typeof区别、为Array添加contains方法
2013-11-24 前言: 上周在工作中遇到了一些跟JS以及前台交互的问题,虽然算不上多么高深,但是在解决时也走了一些弯路,所以就总结一下. 1. JS获取checkboxList所选的值 这 ...
- 在VS2008环境下的C++异常处理
在写DAServer的过程中,一直在重视报文逻辑处理,却没有认认真真地去思考异常处理的问题.曾经我发现我在所有的报文处理函数中均没有考虑报文长度的问题,让我内心不由地捏了一把冷汗.我在新增的故障录波及 ...
- foxmail 6.5升级到7.0版本后,旧邮件的导入处理
随着foxmail 7.0版的火热升级,部分从foxmial 6.5版升级到7.0版的用户可能会出现旧邮件丢失的困扰.这里,foxmail为大家提供的解决方案如下: 打开Foxmail,点击 文件 ...
- Perl 模块 Getopt::Std 和 Getopt::Long
示例程序: getopt.pl; 1 2 3 4 5 6 7 8 #!/usr/bin/perl -w #use strict; use Getopt::Std; use vars qw($opt_a ...
- 【Linux】系统 之 Load
一.查看系统负荷 在Linux系统中,我们一般使用uptime命令查看(w命令和top命令也行).你在终端窗口键入uptime,系统会返回一行信息.这行信息的后半部分,显示"load ave ...
- POJ题目分类
POJ上的一些水题(可用来练手和增加自信) (poj3299,poj2159,poj2739,poj1083,poj2262,poj1503,poj3006,poj2255,poj3094)初期: 一 ...
- DBA_Oracle冷备份案例脚本本法(案例)
2014-08-10 Created By BaoXinjian
- NeHe OpenGL教程 第三十七课:卡通映射
转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...
- Mongodb(2)创建数据库,删除数据库,创建集合,删除集合,显示文档内容
显示所有数据库列表:show dbs > show dbs local .078GB runoob .078GB > 显示当前数据库:db > db runoob > 显示所有 ...