「有关java案例」java语言案例教程
本篇文章给大家谈谈有关java案例,以及java语言案例教程对应的知识点,希望对各位有所帮助,不要忘了收藏本站喔。
本文目录一览:
java常用的几种线程池实例讲解
下面给你介绍4种线程池:
1、newCachedThreadPool:
底层:返回ThreadPoolExecutor实例,corePoolSize为0;maximumPoolSize为Integer.MAX_VALUE;keepAliveTime为60L;unit为TimeUnit.SECONDS;workQueue为SynchronousQueue(同步队列)
通俗:当有新任务到来,则插入到SynchronousQueue中,由于SynchronousQueue是同步队列,因此会在池中寻找可用线程来执行,若有可以线程则执行,若没有可用线程则创建一个线程来执行该任务;若池中线程空闲时间超过指定大小,则该线程会被销毁。
适用:执行很多短期异步的小程序或者负载较轻的服务器
2、newFixedThreadPool:
底层:返回ThreadPoolExecutor实例,接收参数为所设定线程数量nThread,corePoolSize为nThread,maximumPoolSize为nThread;keepAliveTime为0L(不限时);unit为:TimeUnit.MILLISECONDS;WorkQueue为:new LinkedBlockingQueueRunnable() 无解阻塞队列
通俗:创建可容纳固定数量线程的池子,每隔线程的存活时间是无限的,当池子满了就不在添加线程了;如果池中的所有线程均在繁忙状态,对于新任务会进入阻塞队列中(无界的阻塞队列)
适用:执行长期的任务,性能好很多
3、newSingleThreadExecutor
底层:FinalizableDelegatedExecutorService包装的ThreadPoolExecutor实例,corePoolSize为1;maximumPoolSize为1;keepAliveTime为0L;unit为:TimeUnit.MILLISECONDS;workQueue为:new LinkedBlockingQueueRunnable() 无解阻塞队列
通俗:创建只有一个线程的线程池,且线程的存活时间是无限的;当该线程正繁忙时,对于新任务会进入阻塞队列中(无界的阻塞队列)
适用:一个任务一个任务执行的场景
4、NewScheduledThreadPool:
底层:创建ScheduledThreadPoolExecutor实例,corePoolSize为传递来的参数,maximumPoolSize为Integer.MAX_VALUE;keepAliveTime为0;unit为:TimeUnit.NANOSECONDS;workQueue为:new DelayedWorkQueue() 一个按超时时间升序排序的队列
通俗:创建一个固定大小的线程池,线程池内线程存活时间无限制,线程池可以支持定时及周期性任务执行,如果所有线程均处于繁忙状态,对于新任务会进入DelayedWorkQueue队列中,这是一种按照超时时间排序的队列结构
适用:周期性执行任务的场景
最后给你说一下线程池任务执行流程:
当线程池小于corePoolSize时,新提交任务将创建一个新线程执行任务,即使此时线程池中存在空闲线程。
当线程池达到corePoolSize时,新提交任务将被放入workQueue中,等待线程池中任务调度执行
当workQueue已满,且maximumPoolSizecorePoolSize时,新提交任务会创建新线程执行任务
当提交任务数超过maximumPoolSize时,新提交任务由RejectedExecutionHandler处理
当线程池中超过corePoolSize线程,空闲时间达到keepAliveTime时,关闭空闲线程
当设置allowCoreThreadTimeOut(true)时,线程池中corePoolSize线程空闲时间达到keepAliveTime也将关闭
帮我解释一个Java多态的例子
首先应该明白 A a2 = new B()是创建一个B对象并把它转换成A对象。
对于a1它是A类的对象有函数show(D),show(A),a2是B对象,然后转换成A那么它拥有的函数是show(d),show(A)此时A已覆盖,即返回值为(“B and A”)。b是一个B的对象,有函数show(D)(继承A),show(A)覆盖A,show(B)子类自有函数。C和D是B的子类。
a1.show(b)是在A中找到满足条件的方法,调用show(A)函数。result:A and A
a1.show(c)在A中找到show(A).result: A and A
a1.show(d)在A中找到show(D).result: A and D
a2.show(b)在它拥有的函数中找到被B覆盖过的show(A).result: B and A
a2.show(c)找到被B覆盖过的show(A).result: B and A
a2.show(d)show(D)result A and D
b.show(b) show(B) result:B and B
b.show(c) show(B) result: B and B
b.show(d) 上找到A中的show(D) result: A and D
a2.show(d)
JAVA模拟生产者与消费者实例
使用的生产者和消费者模型具有如下特点:
(1)本实验的多个缓冲区不是环形循环的,也不要求按顺序访问。生产者可以把产品放到目前某一个空缓冲区中。
(2)消费者只消费指定生产者的产品。
(3)在测试用例文件中指定了所有的生产和消费的需求,只有当共享缓冲区的数据满足了所有关于它的消费需求后,此共享缓冲区才可以作为空闲空间允许新的生产者使用。
(4)本实验在为生产者分配缓冲区时各生产者间必须互斥,此后各个生产者的具体生产活动可以并发。而消费者之间只有在对同一产品进行消费时才需要互斥,同时它们在消费过程结束时需要判断该消费对象是否已经消费完毕并清除该产品。
Windows
用来实现同步和互斥的实体。在Windows
中,常见的同步对象有:信号量(Semaphore)、
互斥量(Mutex)、临界段(CriticalSection)和事件(Event)等。本程序中用到了前三个。使用这些对象都分
为三个步骤,一是创建或者初始化:接着请求该同步对象,随即进入临界区,这一步对应于互斥量的
上锁;最后释放该同步对象,这对应于互斥量的解锁。这些同步对象在一个线程中创建,在其他线程
中都可以使用,从而实现同步互斥。当然,在进程间使用这些同步对象实现同步的方法是类似的。
1.用锁操作原语实现互斥
为解决进程互斥进人临界区的问题,可为每类临界区设置一把锁,该锁有打开和关闭两种状态,进程执行临界区程序的操作按下列步骤进行:
①关锁。先检查锁的状态,如为关闭状态,则等待其打开;如已打开了,则将其关闭,继续执行步骤②的操作。
②执行临界区程序。
③开锁。将锁打开,退出临界区。
2.信号量及WAIT,SIGNAL操作原语
信号量的初值可以由系统根据资源情况和使用需要来确定。在初始条件下信号量的指针项可以置为0,表示队列为空。信号量在使用过程中它的值是可变的,但只能由WAIT,SIGNAL操作来改变。设信号量为S,对S的WAIT操作记为WAIT(S),对它的SIGNAL操作记为SIGNAL(S)。
WAIT(S):顺序执行以下两个动作:
①信号量的值减1,即S=S-1;
②如果S≥0,则该进程继续执行;
如果
S(0,则把该进程的状态置为阻塞态,把相应的WAITCB连人该信号量队列的末尾,并放弃处理机,进行等待(直至其它进程在S上执行SIGNAL操作,把它释放出来为止)。
SIGNAL(S):顺序执行以下两个动作
①S值加
1,即
S=S+1;
②如果S)0,则该进程继续运行;
如果S(0则释放信号量队列上的第一个PCB(既信号量指针项所指向的PCB)所对应的进程(把阻塞态改为就绪态),执行SIGNAL操作的进程继续运行。
在具体实现时注意,WAIT,SIGNAL操作都应作为一个整体实施,不允许分割或相互穿插执行。也就是说,WAIT,SIGNAL操作各自都好像对应一条指令,需要不间断地做下去,否则会造成混乱。
从物理概念上讲,信号量S)时,S值表示可用资源的数量。执行一次WAIT操作意味着请求分配一个单位资源,因此S值减1;当S0时,表示已无可用资源,请求者必须等待别的进程释放了该类资源,它才能运行下去。所以它要排队。而执行一次SIGNAL操作意味着释放一个单位资源,因此S值加1;若S(0时,表示有某些进程正在等待该资源,因而要把队列头上的进程唤醒,释放资源的进程总是可以运行下去的。
---------------
/**
*
生产者
*
*/
public
class
Producer
implements
Runnable{
private
Semaphore
mutex,full,empty;
private
Buffer
buf;
String
name;
public
Producer(String
name,Semaphore
mutex,Semaphore
full,Semaphore
empty,Buffer
buf){
this.mutex
=
mutex;
this.full
=
full;
this.empty
=
empty;
this.buf
=
buf;
this.name
=
name;
}
public
void
run(){
while(true){
empty.p();
mutex.p();
System.out.println(name+"
inserts
a
new
product
into
"+buf.nextEmptyIndex);
buf.nextEmptyIndex
=
(buf.nextEmptyIndex+1)%buf.size;
mutex.v();
full.v();
try
{
Thread.sleep(1000);
}
catch
(InterruptedException
e)
{
e.printStackTrace();
}
}
}
}
---------------
/**
*
消费者
*
*/
public
class
Customer
implements
Runnable{
private
Semaphore
mutex,full,empty;
private
Buffer
buf;
String
name;
public
Customer(String
name,Semaphore
mutex,Semaphore
full,Semaphore
empty,Buffer
buf){
this.mutex
=
mutex;
this.full
=
full;
this.empty
=
empty;
this.buf
=
buf;
this.name
=
name;
}
public
void
run(){
while(true){
full.p();
mutex.p();
System.out.println(name+"
gets
a
product
from
"+buf.nextFullIndex);
buf.nextFullIndex
=
(buf.nextFullIndex+1)%buf.size;
mutex.v();
empty.v();
try
{
Thread.sleep(1000);
}
catch
(InterruptedException
e)
{
e.printStackTrace();
}
}
}
}
-------------------------
/**
*
缓冲区
*
*/
public
class
Buffer{
public
Buffer(int
size,int
nextEmpty,int
nextFull){
this.nextEmptyIndex
=
nextEmpty;
this.nextFullIndex
=
nextFull;
this.size
=
size;
}
public
int
size;
public
int
nextEmptyIndex;
public
int
nextFullIndex;
}
-----------------
/**
*
此类用来模拟信号量
*
*/
public
class
Semaphore{
private
int
semValue;
public
Semaphore(int
semValue){
this.semValue
=
semValue;
}
public
synchronized
void
p(){
semValue--;
if(semValue0){
try
{
this.wait();
}
catch
(InterruptedException
e)
{
e.printStackTrace();
}
}
}
public
synchronized
void
v(){
semValue++;
if(semValue=0){
this.notify();
}
}
}
------------------------
public
class
Test
extends
Thread
{
public
static
void
main(String[]
args)
{
Buffer
bf=new
Buffer(10,0,0);
Semaphore
mutex=new
Semaphore(1);
Semaphore
full=new
Semaphore(0);
Semaphore
empty=new
Semaphore(10);
//new
Thread(new
Producer("p001",mutex,full,empty,bf)).start();
Producer
p=new
Producer("p001",mutex,full,empty,bf);
new
Thread(new
Producer("p002",mutex,full,empty,bf)).start();
new
Thread(new
Producer("p003",mutex,full,empty,bf)).start();
new
Thread(new
Producer("p004",mutex,full,empty,bf)).start();
new
Thread(new
Producer("p005",mutex,full,empty,bf)).start();
try{
sleep(3000);
}
catch(Exception
ex)
{
ex.printStackTrace();
}
new
Thread(new
Customer("c001",mutex,full,empty,bf)).start();
new
Thread(new
Customer("c002",mutex,full,empty,bf)).start();
new
Thread(new
Customer("c003",mutex,full,empty,bf)).start();
new
Thread(new
Customer("c004",mutex,full,empty,bf)).start();
new
Thread(new
Customer("c005",mutex,full,empty,bf)).start();
}
}
--------------------------------------------
java 多线程的例子
多线程实际上就是多个线程同时运行,至于那个先完成是不能确定的。
* @author Rollen-Holt 实现Runnable接口
* */
class hello implements Runnable {
public hello() {
}
public hello(String name) {
this.name = name;
}
public void run() {
for (int i = 0; i 5; i++) {
System.out.println(name + "运行 " + i);
}
}
public static void main(String[] args) {
hello h1=new hello("线程A");
Thread demo= new Thread(h1);
hello h2=new hello("线程B");
Thread demo1=new Thread(h2);
demo.start();
demo1.start();
}
private String name;
}
可能运行结果:
求JAVA封装和继承案例?
封装性是整个面向对象的第一大特性,所谓的封装性是指类内部的操作对外部不可见。
范例:观察如下的程序问题
class Person { // 类名称的单词首字母必须大写
String name ; // 姓名,是一个字符串所以使用String
int age ; // 年龄是一个整数,所以使用int
public void tell(){ // 定义一个方法
System.out.println("姓名:" + name + ",年龄:" + age) ;
}
}
public class ClassDemo {
public static void main(String args[]){
Person per = new Person() ;
per.name = "张三" ;
per.age = -30 ;
per.tell() ;
}
}
此时的程序从技术(语法)上而言没有任何的问题,但是从实际的生活(业务)上来看,一个人的年龄绝对不可能是-30岁,所以这个时候造成问题的主要原因就是类中的操作对外部可见。
此时,就可以通过封装性来解决此类问题,如果现在要想对类中的属性或方法封装,可以直接使用private关键字完成。
class Person { // 类名称的单词首字母必须大写
private String name ; // 姓名,是一个字符串所以使用String
private int age ; // 年龄是一个整数,所以使用int
public void tell(){ // 定义一个方法
System.out.println("姓名:" + name + ",年龄:" + age) ;
}
}
public class ClassDemo {
public static void main(String args[]){
Person per = new Person() ;
per.name = "张三" ;
per.age = 99999 ;
per.tell() ;
}
}
此时,程序编译之后出现了以下的错误信息:
ClassDemo.java:11: name has private access in Person
per.name = "张三" ;
^
ClassDemo.java:12: age has private access in Person
per.age = 99999 ;
^
2 errors
由于name和age两个属性被private声明了(封装了,私有)所以,现在根本无法被外部所访问,很明显,此时的属性绝对安全,但是封装归封装了,一个问题就出现了,现在的属性无法操作了,无法操作就没有意义了,所以此时,就可以给出一个概念,以后凡是类中的属性在定义的时候必须封装,封装之后的属性一定要通过setter、getter方法设置和取得。Setter和getter方法本身有自己的命名规范。
• 例如:private String name ;
• setter:public void setName(String na)
• getter:public String getName()
class Person { // 类名称的单词首字母必须大写
private String name ; // 姓名,是一个字符串所以使用String
private int age ; // 年龄是一个整数,所以使用int
public void setName(String n){
name = n ;
}
public void setAge(int a){
age = a ;
}
public String getName(){
return name ;
}
public int getAge(){
return age ;
}
public void tell(){ // 定义一个方法
System.out.println("姓名:" + name + ",年龄:" + age) ;
}
}
public class ClassDemo {
public static void main(String args[]){
Person per = new Person() ;
per.setName("张三") ;
per.setAge(99999) ;
per.tell() ;
}
}
此时,虽然是通过setter和getter方法间接的访问了私有属性,但是却没有检验,一旦需要检验,则检验的操作应该放在setter语句之中。
所有的设置应该在setter中完成,而getter方法只是将内容简单的返回即可。
class Person { // 类名称的单词首字母必须大写
private String name ; // 姓名,是一个字符串所以使用String
private int age ; // 年龄是一个整数,所以使用int
public void setName(String n){
name = n ;
}
public void setAge(int a){
if(a0 a200){
age = a ;
}
}
public String getName(){
return name ;
}
public int getAge(){
return age ;
}
public void tell(){ // 定义一个方法
System.out.println("姓名:" + name + ",年龄:" + age) ;
}
}
public class ClassDemo {
public static void main(String args[]){
Person per = new Person() ;
per.setName("张三") ;
per.setAge(99) ;
per.tell() ;
}
}
此时,就通过封装性解决了设置错误内容的问题。
一定要注意的是,封装性出了在属性声明上外,也可以在方法上声明。
private void info(){ // 私有方法
System.out.println("*************************") ;
}
public void tell(){ // 定义一个方法
this.info() ;
System.out.println("姓名:" + name + ",年龄:" + age) ;
}
如果现在调用的是本类中的方法,可以通过“this.方法()”的形式访问。
关于有关java案例和java语言案例教程的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。