java中稍微有些陌生的关键字

1、 instance of

  java中,instance of 用来指出某个对象是否为某个特定类的实例,如果是返回一个bool类型,来指出该对象是否为某个特定类或其子类的一个实例

  resutl = object instance of class

interface A{}
class B implements A
{

}
class C  extends B
{

}
public class InstanceOfTest {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		A a = null;
		B b = null;
		boolean result;

		 System.out.println("instanceoftest test case 1: ------------------");
		 result = a instanceof A;
		 System.out.println("a instanceof A :"+result);

		 result = b instanceof B;
		 System.out.println("b instanceof B :"+result);

		 System.out.println("/ninstanceoftest test case 2: ------------------");
		 a = new B();
		 b = new B();

		 result = a instanceof A;
		 System.out.println("a instanceof A :"+result);
		 result = a instanceof B;
		 System.out.println("a instanceof B :"+result);

		 result = b instanceof A;
		 System.out.println("b instanceof A :"+result);
		 result = b instanceof B;
		 System.out.println("b instanceof B :"+result);

		  System.out.println("/ninstanceoftest test case 3: ------------------");
		  A b2 = new C();
		  result = b2 instanceof A;
		  System.out.println("b2 instanceof A :"+result);
		  result = b2 instanceof B;
		  System.out.println("b2 instanceof B :"+result);
		  result = b2 instanceof C;
		  System.out.println("b2 instanceof C :"+result);
	}

}

  2、transient

Q:transient关键字能实现什么?

A:当对象被序列化时(写入字节序列到目标文件)时,transient阻止实例中那些用此关键字声明的变量持久化;

当对象被反序列化时(从源文件读取字节序列进行重构),这样的实例变量不会被持久化和回复。例如,当反

序列化对象----数据流(例如,文件)可能不存在是,原因是你的对象中存在类型为java.io.InputStream的变量

,序列化时这些变量引用的输入流无法被打开。

  总之当你不需要某个变量被序列化时,则将该变量设置为 transient变量

3、native

  java native 方法是指本地方法,当在方法中调用一些不是由java语言写的代码或者在方法中调用java语言直接操纵计算机硬件时声明为native方法。

java中,通过JNI(java native interface ,java本地接口)来实现本地化

native方法一般用于两种情况:

1) 在方法中调用一些不是由java语言写的代码

2) 在方法中用java语言直接操纵计算机硬件

JNI的书写步骤:

a、编写带有native声明的方法的java类

b、使用javac命令编译编写的java类

c、使用java -jni ***来生成后缀名为.h的头文件

d、使用其他语言(C、c++)实现本地方法

e、将本地方法编写的文件生成动态链接库

4、synchronized

Q:为什么要用synchronized这个关键字

A:先看个实例

package com.lost.syn;

import java.awt.geom.FlatteningPathIterator;

class Account{
	String name;
	float  amount;
	public Account(String name, float amount)
	{
		this.name = name;
		this.amount = amount;
	}

	public void deposit(float amt)
	{
		float tmp = amount;
		tmp += amt;
		try {
			System.out.println("存入100");
			Thread.sleep(100);
		} catch (Exception e) {
			// TODO: handle exception
		}
		this.amount = tmp;
	}

	public void withdraw(float amt)
	{
		float tmp = this.amount;
		tmp -= amt;
		try {
			System.out.println("取出100");

			Thread.sleep(100);
		} catch (Exception e) {
			// TODO: handle exception
		}
		this.amount = tmp;
	}
	public float getBalance()
	{
		return this.amount;
	}
}
public class SynDemo {
	public static int NUM_OF_THREAD = 5000;
	static Thread[] threads = new Thread[NUM_OF_THREAD];
	public static void main(String args[])
	{
		final Account cc =new Account("john",1000.0f);
		for(int i=0;i<NUM_OF_THREAD; i++)
		{
			threads[i] = new Thread(new Runnable() {

				@Override
				public void run() {
					// TODO Auto-generated method stub
					cc.deposit(100.0f);
					cc.withdraw(100.0f);
				}
			});
			threads[i].start();
		}
		for(int i=0; i<NUM_OF_THREAD; i++)
		{
			try {
				threads[i].join();
			} catch (Exception e) {
				// TODO: handle exception
			}
		}
		System.out.println("Finally John‘s Balance is "+cc.getBalance());
	}
}

  

Finally John‘s Balance is 1200.0

Finally John‘s Balance is 1400.0

线程一 和线程二同时进行 初始balance为1000

线程一存钱  线程二也存钱  同时进行 基数都是1000  存完后 基数编程了1100 而不是1200 此时如果再同时取钱的话 又变成了1000 如果不同时取得话 就变成了900

每次的结果都不一定相同,因为是有很多线程同时在存取。如果你每次运行得到的都是1000,恭喜你,你的电脑配置比较高,所以你可以把线程的数量开的稍微大一些。

这就是多线程中同步的问题,在我们的程序中,Account会同时被多个线程访问,这就是一个竞争资源,通常称作竞态条件。对于这样的多个线程共享的资源我们必须进行同步,以避免一个线程的改动被另一个线程所覆盖。在我们这个程序中,Account中的amount是一个竞态条件,所以所有对amount的修改访问都要进行同步,我们将deposit和withdraw方法进行同步

public synchronized void deposit(float amt)
	{
		float tmp = amount;
		tmp += amt;
		try {
			System.out.println("存入100");
			Thread.sleep(100);
		} catch (Exception e) {
			// TODO: handle exception
		}
		this.amount = tmp;
	}

	public synchronized void withdraw(float amt)
	{
		float tmp = this.amount;
		tmp -= amt;
		try {
			System.out.println("取出100");

			Thread.sleep(100);
		} catch (Exception e) {
			// TODO: handle exception
		}
		this.amount = tmp;
	}

  同步加锁的是对象而不是代码段

  如果你的类中有一个同步方法,这个方法可以被两个不同的线程同时执行,只要每一个线程自己创建一个的该类的实例即可。

class Foo extends Thread
{
	private int val;
	public Foo(int v)
	{
		val = v;
	}
	public synchronized void printVal(int v)
	{
		while(true)
		{
			System.out.println(v);
		}
	}

	public void run()
	{
		printVal(val);
	}
}

  类的同步

  要实现真正的断面,你必须同步一个全局对象或者对类进行同步。

class Foo extends Thread
{
	private String name;
	private String val;
//	private static Object lock = new Object();

	public Foo(String name, String v)
	{
		this.name = name;
		this.val = v;
	}
	public  void printVal()
	{
		synchronized(Foo.class){

			while(true)
			{
				System.out.println(name+val);
			}
		}

	}

	public void run()
	{
		printVal();
	}
}

  

对于String类型 如下例  有jVM的优化机制 “”在内存中只保存一份,除非用new String 重新创建对象

class Foo extends Thread
{
	private String name;
	private String val;
//	private static Object lock = new Object();

	public Foo(String name, String v)
	{
		this.name = name;
		this.val = v;
	}
	public  void printVal()
	{
		synchronized(val){

			while(true)
			{
				System.out.println(name+val);
			}
		}

	}

	public void run()
	{
		printVal();
	}
}

  

//main 方法中
String value = "printVal";
Foo f1 = new Foo("foo 1:",new String("foo 1"));
f1.start();

Foo f2 = new Foo("foo 2:",new String("foo 2"));
f2.start();

Foo f1 = new Foo("foo 1:",value );
f1.start();

Foo f2 = new Foo("foo 2:",value );
f2.start();

  上面两种关于main中的使用是不一样的

小结:

  synchronized关键字的作用域有两种:

  1、是某个对象实例内, synchronized aMethod(){} 可以防止多个线程同时访问这个对象的synchronized方法(如果一个对象有多个synchronized方法,只要一个线程访问了其中的一个synchronized方法,其他线程不能同时访问这个对象中任何一个synchronized方法)。这时,不同的丢向实例的synchronized方法是不相干扰的。也就是说,其他线程照样可以同时访问相同类的另一个对象实例中synchronized方法。

  2、除了方法前使用synchronized关键字,synchronized关键字还可以用于方法中的某个区块中,表示只对这个区块的资源实行互斥访问。用法是: synchronized(this){/*区块*/},它的作用域是当前对象;

  3、synchronized关键字是不能继承的,也就是说,基类的方法synchronized f(){} 在继承类中并不自动是synchronized f(){} ,而是变成了f(){}.继承类需要你显示的指定它的某个方法为synchronized方法。

java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码。

  一、当两个并发线程访问同一个对象object中的这个synchronized(this)同步代码块时,一个时间内只能有一个线程得到执行。另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块。

  二、然而,当一个线程访问object的一个synchronized(this)同步代码块时,另一个线程仍然可以访问该object中的非synchronized(this)代码块。

  三、尤其关键的是,当一个线程访问object的一个synchronized(this) 同步代码块时,其他线程对object中的多有其他synchronized同步代码块的访问将被阻塞。

  四、第三个例子同样适用其他同步代码块。也就是说,当一个线程访问object的一个synchronized同步代码块时,它就获得了这个object的对象锁。结果,其他线程对该object对象所有同步代码部分的访问都被暂时组设

  五、以上规则对其他对象锁同样适用。

(java中不能在类外定义全局变量,只能通过一个类中定义公用,静态的变量来实现一个全局变量)

  synchronized方法控制对类成员变量的访问:每个类实例对应一把锁,每个synchronized方法都必须获得调用该方法的类实例的锁方能执行,否则所属线程阻塞,方法一旦执行,就独占该锁,直到从该方法返回时才将锁释放,伺候被阻塞的线程方能获得该锁,重新进入可执行状态。这种机制确保了同一时刻对于每一个类实例,其所有声明为 synchronized的成员函数中至多只有一个处于可执行状态(因为至多只有一个能够获得该类实例对应的锁),从而有效避免了类成员变量的访问冲突(只要所有可能访问类成员变量的方法均被声明为synchronized)。(第一次加synchronized的时候)

在java中,不光是类实例,每一个类也对应一把锁,这样我们有可将类的成员函数声明为synchronized,以控制其对类的静态成员变量的访问。

synchronized方法的缺陷:若将一个大的方法声明为synchronized将会大大影响效率,典型地,若将线程类的方法run声明为synchronized,由于在线程的整个声明周期内他一直在运行,因此导致它对本类任何synchronized 方法的调用都永远不会成功。当我们可以通过将访问类成员变量的代码放到专门的方法中,将其声明为synchronized,并在主方法中调用来解决这一问题,但是java为我们提供了更好的解决办法,那就是synchronized块。

2、synchronized 块: 通过synchronized关键字声明synchronized块。

可以针对任意代码块,且可以任意指定上锁的对象,故灵活性较高。

一、当两个并发线程访问同一个对象object 中的这个synchronized同步代码块时,一个时间内只能有一个线程得到执行。另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块。

二、然而,当一个线程访问object的一个synchronized同步代码块时,另一个线程仍然可以范文该object中的非synchronized同步代码块。

三、当一个线程访问object的一个synchronized同步代码块时,其他线程仍然可以访问该object 中所有其他synchronized(this)同步代码块的访问将被阻塞。

5、strictfp(strict float point)精确浮点

  如果你想让你的浮点运算更加精确,而且不会因为不同的硬件平台执行的结果不一致的话,可以使用关键字 strictfp

时间: 2024-10-10 22:34:30

java中稍微有些陌生的关键字的相关文章

Java中关于原子操作和volatile关键字

Java中关于原子操作和volatile关键字 第一种:采用同步synchronized解决,这样虽然解决了问题,但是也降低了系统的性能. 第二种:采用原子性数据Atomic变量,这是从JDK1.5开始才存在的针对原子性的解决方案,这种方案也是目前比较好的解决方案了.

Java 中几个重要的关键字

Java中的关键字特别多,大致如下: 访问控制 private protected public 类,方法和变量修饰符 abstract class extends final implements interface native new static strictfp synchronized transient volatile 程序控制 break continue return do while if else for instanceof switch case default 异常

Java中的throws与throw关键字

作者:苗老师,华清远见嵌入式学院讲师. Java中的异常处理还是比较有意思的!就是该你管就你管,不是你该管的,最好不要越级管理!不然我这级管理存在就没有意义! Java的异常处理是通过5个关键字来实现的:try,catch,throw,throws,finally.这里我主要说一下throw,throws. throws语句 throws总是出现在方法声明时,用来标明该成员方法可能抛出异常.如果是多个异常,使用逗号隔开.对大 多数Exception子类来说,Java 编译器会强迫你声明在一个成员

Java中替代C# ref/out 关键字方案:

刚学习Java不久,今天遇到一个问题,需要在方法中修改传入的对象的值,确切的说是需要使用一个方法,创建一个对象,并把其引用返回,熟悉C#的我的第一反应就是C#中的ref/out关键字,结果发现Java中没有类似的关键字,所以只能想想如何解决此问题. 参数传递:方法的参数传递有两种,一种是值传递,一种是引用传递,但是其实都是拷贝传递. 值传递:就是把传递的[数据本身拷贝一份],传入方法中对其进行操作,拷贝的是值.引用传递:就是把指向某个对象的[引用拷贝一份],传入方法中通过此引用可以对对象进行操作

Java中的break和continue关键字使用总结

一.作用和区别 break的作用是跳出当前循环块(for.while.do while)或程序块(switch).在循环块中的作用是跳出当前正在循环的循环体.在程序块中的作用是中断和下一个case条件的比较. continue用于结束循环体中其后语句的执行,并跳回循环程序块的开头执行下一次循环,而不是立刻循环体. 二.其他用途 break和continue可以配合语句标签使用.这个都很简单,下面给个综合实例,看看就明白 了: /** * Created by IntelliJ IDEA. * U

java中 static,final,transient,volatile关键字的作用

static 和final static  静态修饰关键字,可以修饰 变量,程序块,类的方法: 当你定义一个static的变量的时候jvm会将将其分配在内存堆上,所有程序对它的引用都会指向这一个地址而不会重新分配内存: 修饰一个程序块的时候(也就是直接将代码写在static{...}中)时候,虚拟机就会优先加载静态块中代码,这主要用于系统初始化:当修饰一个类方法时候你就可以直接通过类来调用而不需要新建对象. final 只能赋值一次:修饰变量.方法及类,当你定义一个final变量时,jvm会将其

Java中的Serializable接口transient关键字,及对象IO

1.什么是序列化和反序列化Serialization是一种将对象转为为字节流的过程:deserialization是将字节流恢复为对象的过程. 2.什么情况下需要序列化a)当你想把的内存中的对象保存到一个文件中或者数据库中时候:b)当你想用套接字在网络上传送对象的时候:c)当你想通过RMI传输对象的时候: 3.如何实现序列化将需要序列化的类实现Serializable接口就可以了,Serializable接口和Cloneable接口一样,不含任何方法,是个标记接口. 4.代码分析 package

谈谈java中的super和this关键字

知识点: 在java类中使用super引用父类的成分,用this引用当前对象 this可以修饰属性.构造器.方法 super可以修饰属性.构造器.方法 一:this关键字 this可以修饰属性.构造器.方法:用this引用当前对象 (1)this修饰属性,调用类的属性 //set方法public void setName(String name) { this.name = name;} //有参数构造函数 public Person(String name){ this.name=name;}

JAVA中的super和this关键字的使用

一 this关键字 this关键字可以出现在构造方法和实例方法中,不能出现在静态方法中,这是因为静态方法可以用类名来调用,这时可能还没有任何对象诞生. this主要有两种用法: 1 用在构造方法中,调用本类的其他构造方法.  格式为  this([实参列表]);   通过this调用本类的其他构造方法时,该语句必须出现在构造方法中,并且必须作为第一条语句出现. 2 代指当前对象 例如: 1 public class Person { 2 3 private String name; 4 5 pr