外贸网站如何推广,wordpress分栏插件,智能网站建设公司排名,企业怎样做好网站建设哪个关键字可以对对象加互斥锁#xff1f;#xff08;#xff09;
A synchronized
B volatile
C serialize
D static
synchronized的4种用法
1.方法声明时使用,放在范围操作符(public等)之后,返回类型声明(void等)之前.这时,线程获得的是成员锁,即一次只能有一个线程进…哪个关键字可以对对象加互斥锁
A synchronized
B volatile
C serialize
D static
synchronized的4种用法
1.方法声明时使用,放在范围操作符(public等)之后,返回类型声明(void等)之前.这时,线程获得的是成员锁,即一次只能有一个线程进入该方法,其他线程要想在此时调用该方法,只能排队等候,当前线程(就是在synchronized方法内部的线程)执行完该方法后,别的线程才能进入. public synchronized void synMethod() {//方法体}
2.对某一代码块使用,synchronized后跟括号,括号里是变量,这样,一次只有一个线程进入该代码块.此时,线程获得的是成员锁.例如: public int synMethod(int a1){synchronized(a1) {//一次只能有一个线程进入}} 3.synchronized后面括号里是一对象,此时,线程获得的是对象锁.例如:
public class MyThread implements Runnable {public static void main(String args[]) {MyThread mt new MyThread();Thread t1 new Thread(mt, t1);Thread t2 new Thread(mt, t2);Thread t3 new Thread(mt, t3);Thread t4 new Thread(mt, t4);Thread t5 new Thread(mt, t5);Thread t6 new Thread(mt, t6);t1.start();t2.start();t3.start();t4.start();t5.start();t6.start();}public void run() {synchronized (this) {System.out.println(Thread.currentThread().getName());}}
}
对于3,如果线程进入,则得到当前对象锁,那么别的线程在该类所有对象上的任何操作都不能进行.在对象级使用锁通常是一种比较粗糙的方法。为什么要将整个对象都上锁而不允许其他线程短暂地使用对象中其他同步方法来访问共享资源如果一个对象拥有多个资源就不需要只为了让一个线程使用其中一部分资源就将所有线程都锁在外面。由于每个对象都有锁可以如下所示使用虚拟对象来上锁
class FineGrainLock {MyMemberClass x, y;Object xlock new Object(), ylock new Object();public void foo() {synchronized(xlock) {//access x here}//do something here - but dont use shared resourcessynchronized(ylock) {//access y here}}public void bar() {synchronized(this) {//access both x and y here}//do something here - but dont use shared resources}}4.synchronized后面括号里是类,此时,线程获得的是对象锁.例如:
class ArrayWithLockOrder{private static long num_locks 0;private long lock_order;private int[] arr;public ArrayWithLockOrder(int[] a){arr a;synchronized(ArrayWithLockOrder.class) {//-----这里num_locks; // 锁数加 1。lock_order num_locks; // 为此对象实例设置唯一的 lock_order。}}public long lockOrder(){return lock_order;}public int[] array(){return arr;}}class SomeClass implements Runnable{public int sumArrays(ArrayWithLockOrder a1,ArrayWithLockOrder a2){int value 0;ArrayWithLockOrder first a1; // 保留数组引用的一个ArrayWithLockOrder last a2; // 本地副本。int size a1.array().length;if (size a2.array().length){if (a1.lockOrder() a2.lockOrder()) // 确定并设置对象的锁定{ // 顺序。first a2;last a1;}synchronized(first) { // 按正确的顺序锁定对象。synchronized(last) {int[] arr1 a1.array();int[] arr2 a2.array();for (int i0; isize; i)value arr1[i] arr2[i];}}}return value;}public void run() {//}}
对于4,如果线程进入,则线程在该类中所有操作不能进行,包括静态变量和静态方法,实际上,对于含有静态方法和静态变量的代码块的同步,我们通常用4来加锁.
Volatile原理
Java语言提供了一种稍弱的同步机制即volatile变量用来确保将变量的更新操作通知到其他线程。当把变量声明为volatile类型后编译器与运行时都会注意到这个变量是共享的因此不会将该变量上的操作与其他内存操作一起重排序。volatile变量不会被缓存在寄存器或者对其他处理器不可见的地方因此在读取volatile类型的变量时总会返回最新写入的值。 在访问volatile变量时不会执行加锁操作因此也就不会使执行线程阻塞因此volatile变量是一种比sychronized关键字更轻量级的同步机制。 当对非 volatile 变量进行读写的时候每个线程先从内存拷贝变量到CPU缓存中。如果计算机有多个CPU每个线程可能在不同的CPU上被处理这意味着每个线程可以拷贝到不同的 CPU cache 中。 而声明变量是 volatile 的JVM 保证了每次读变量都从内存中读跳过 CPU cache 这一步。
当一个变量定义为 volatile 之后将具备两种特性 1.保证此变量对所有的线程的可见性这里的“可见性”如本文开头所述当一个线程修改了这个变量的值volatile 保证了新值能立即同步到主内存以及每次使用前立即从主内存刷新。但普通变量做不到这点普通变量的值在线程间传递均需要通过主内存来完成。 2.禁止指令重排序优化。有volatile修饰的变量赋值后多执行了一个“load addl $0x0, (%esp)”操作这个操作相当于一个内存屏障指令重排序时不能把后面的指令重排序到内存屏障之前的位置只有一个CPU访问内存时并不需要内存屏障什么是指令重排序是指CPU采用了允许将多条指令不按程序规定的顺序分开发送给各相应电路单元处理。
对象的串行化Serialization
一、串行化的概念和目的 1.什么是串行化 对象的寿命通常随着生成该对象的程序的终止而终止。有时候可能需要将对象的状态保存下来在需要时再将对象恢复。我们把对象的这种能记录自己的状态以便将来再生的能力。叫作对象的持续性(persistence)。对象通过写出描述自己状态的数值来记录自己 这个过程叫对象的串行化(Serialization) 。串行化的主要任务是写出对象实例变量的数值。如果交量是另一对象的引用则引用的对象也要串行化。这个过程是递归的串行化可能要涉及一个复杂树结构的单行化包括原有对象、对象的对象、对象的对象的对象等等。对象所有权的层次结构称为图表(graph)。 2.串行化的目的 Java对象的单行化的目标是为Java的运行环境提供一组特性如下所示 1) 尽量保持对象串行化的简单扼要 但要提供一种途径使其可根据开发者的要求进行扩展或定制。 2) 串行化机制应严格遵守Java的对象模型 。对象的串行化状态中应该存有所有的关于种类的安全特性的信息。 3) 对象的串行化机制应支持Java的对象持续性。 4) 对象的串行化机制应有足够的 可扩展能力以支持对象的远程方法调用(RMI)。 5) 对象串行化应允许对象定义自身 的格式即其自身的数据流表示形式可外部化接口来完成这项功能。
二、串行化方法 从JDK1.1开始Java语言提供了对象串行化机制 在java.io包中接口Serialization用来作为实现对象串行化的工具 只有实现了Serialization的类的对象才可以被串行化。 Serializable接口中没有任何的方法。当一个类声明要实现Serializable接口时只是表明该类参加串行化协议而不需要实现任何特殊的方法。下面我们通过实例介绍如何对对象进行串行化。 1.定义一个可串行化对象 一个类如果要使其对象可以被串行化必须实现Serializable接口。我们定义一个类Student如下
import java.io.Serializable; public class Student implements Serializable { int id;// 学号 String name;// 姓名 int age;// 年龄 String department; // 系别 public Student(int id, String name, int age, String department) { this.id id; this.name name; this.age age; this.department department; } } 2.构造对象的输入输出流 要串行化一个对象必须与一定的对象输出输入流联系起来通过对象输出流将对象状态保存下来再通过对象输入流将对象状态恢复。 java.io包中提供了ObjectInputStream和ObjectOutputStream将数据流功能扩展至可读写对象 。在ObjectInputStream 中用readObject()方法可以直接读取一个对象ObjectOutputStream中用writeObject()方法可以直接将对象保存到输出流中。
FileInputStream fi new FileInputStream(data.ser); ObjectInputStream si new ObjectInputStream(fi); try { stu (Student) si.readObject(); si.close(); } catch (IOException e) { System.out.println(e); } System.out.println(Student Info:); System.out.println(ID: stu.id); System.out.println(Name: stu.name); System.out.println(Age: stu.age); System.out.println(Dep: stu.department); } }
运行结果 Student Info: ID:981036 Name:LiuMing Age:18 Dep:CSD 在这个例子中我们首先定义了一个类Student实现了Serializable接口 然后通过对象输出流的writeObject()方法将Student对象保存到文件 data.ser中 。之后通过对家输入流的readObjcet()方法从文件data.ser中读出保存下来的Student对象 。从运行结果可以看到通过串行化机制可以正确地保存和恢复对象的状态。
接着我们看看别人的评论
synchronized 关键字 : 用来给对象和方法或者代码块加锁当它锁定一个方法或者一个代码块的时候同一时刻最多只有一个线程执行这个段代码。
volatile用来确保将变量的跟新操作通知到其他线程当把变量声明为volatile类型后编译器与运行时都会注意到这个变量是共享的因此不会将该变量上的操作与其他内存操作一起重排序。然而在访问volatile变量时不会执行加锁操作因此也就不会使执行线程阻塞因此volatile变量是一种比 synchronized关键字更轻量级的同步机制。
serializeJava 对象序列化为二进制文件。
static关键字 static关键字可以修饰变量方法静态代码块。 静态变量: 由static修饰的变量称为静态变量 静态变量属于类而不属于某个对象 静态变量它的副本只有一个(静态变量在类中只加载一) 静态方法 在静态方法中只能调用静态变量和静态方法 在非静态方法中可以调用静态方法或者变量。 在静态方法中不能使用this和super关键字。 静态代码块 作用:用来给静态成员变量初始化
答案A
文章仅个人理解来在各大网站。如有不合理之处欢迎吐槽。
阅读目录置顶)(长期更新计算机领域知识https://blog.csdn.net/weixin_43392489/article/details/102380691
阅读目录置顶)(长期更新计算机领域知识https://blog.csdn.net/weixin_43392489/article/details/102380882
阅读目录置顶)(长期科技领域知识https://blog.csdn.net/weixin_43392489/article/details/102600114
歌谣带你看java面试题 https://blog.csdn.net/weixin_43392489/article/details/102675944