git config --global http.sslVerify false
public class Test {
//不能正確調換值
public static void swap(Integer a,Integer b){
Integer t=a;
a=b;
b=t;
System.out.println("a="+a);
System.out.println("b="+b);
}
public static void main(String[] args) {
Integer a=1;
Integer b=2;
System.out.println("a="+a);
System.out.println("b="+b);
System.out.println("----------");
swap(a, b);
System.out.println("----------");
System.out.println("a="+a);
System.out.println("b="+b);
}
}
在內存中,真實的值放在heap中,變量a,b放在棧中,a,b保存的是值在heap中的地址,當調用swap方法時,形參也是保存在棧中,是新的變量,指向heap中真的值,并沒有修改原先a,b的指向,所以無法交換值。
matches方法返回true,裝配bean,返回false,不裝配bean,在需要可能裝配的bean的方法和類上加上注解@Conditional(XXXCondition.class)
@Component
public class AllBeanPostProcessor implements BeanPostProcessor{
//對象屬性設置方法完成后,init方法執行前執行
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("BeforeInit="+beanName);
return bean;
}
//init方法執行后執行
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("AfterInit="+beanName);
return bean;
}
}
@Component
public class MyBeanFactoryPostProcessor2 implements BeanDefinitionRegistryPostProcessor{
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
// TODO Auto-generated method stub
}
//可以動態把對象注入spring對象
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
for (int i = 0; i < 10; i++) {
BeanDefinitionBuilder b=BeanDefinitionBuilder.rootBeanDefinition(User.class);
b.addPropertyValue("name", "admin"+i);
registry.registerBeanDefinition("user"+i, b.getBeanDefinition());
}
}
}
關鍵字
package test;
public class TestThread extends Thread{
private volatile boolean stop=false;
@Override
public void run() {
int i=0;
while(!stop){
i++;
}
System.out.println("完成="+i);
}
public void setStop(){
stop=true;
}
public boolean getStop(){
return stop;
}
}
volatile關鍵字只能保證多個線程間的可見性,但是不具備同步性,可以算得上是輕量級的
synchronized,性能要比synchronized高,不會造成阻塞。一般volatile用于多個線程之間的可見的變量操作,并不能代替synchronized的同步功能。
例如:9點的時候,客戶A發起select語句,大概需要執行10分鐘,返回結果100,在9點5分的時候,客戶B發起一條update語句,把100更新為200.當10分鐘后,客戶A得到的結果還是100或者返回異常snapshot too old。因為oracle數據庫有數據一致性的保證,客戶9點查詢時,數據庫會把數據復制到undo的副本,給客戶返回的就是這個副本,如果同時多個客戶端進行update操作,可能導致副本找不到,但是無論如何,不會返回修改過的數值。
在一個對象中的多個方法上都加上synchronized,代表同時執行這些方法時,是同步的,同步鎖是屬于對象的不是單個方法的。
package test;
public class Test6 {
public synchronized void get1(String s){
System.out.println(s);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public synchronized void get2(String s){
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(s);
}
public static void main(String[] args) {
final Test6 t =new Test6();
new Thread(new Runnable() {
@Override
public void run() {
t.get1("a");
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
t.get2("b");
}
}).start();
}
}
多個線程訪問同多個對象,同步方法加static,表示此方法屬于類,所有此對象的此方法執行需要同步
package test;
public class Test5 {
public static synchronized void get(String s){
if("a".equals(s)){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(s);
}
public static void main(String[] args) {
final Test5 t =new Test5();
final Test5 t1 =new Test5();
new Thread(new Runnable() {
@Override
public void run() {
t.get("a");
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
t1.get("b");
}
}).start();
}
}
多個線程使用一把鎖,多個線程訪問同一個對象的方法或者屬性。
package test;
public class Test4 {
public synchronized void get(String s){
if("c".equals(s)){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(s);
}
public static void main(String[] args) {
final Test4 t =new Test4();
new Thread(new Runnable() {
@Override
public void run() {
t.get("a");
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
t.get("b");
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
t.get("c");
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
t.get("d");
}
}).start();
}
}