锁重入, 对象synchronized 当线程A 得到了 对象锁,再次请求对象时,是可以再次获取 这个对象锁的
package com.study.thread;
public class CongRuSuo {
public synchronized void method1(){
System.out.println("metho1");
method2();
}
public synchronized void method2(){
System.out.println("metho2");
method3();
}
public synchronized void method3(){
System.out.println("metho3");
}
public static void main(String[] args) {
CongRuSuo t1 = new CongRuSuo();
new Thread(new Runnable() {
@Override
public void run() {
t1.method1();
}
}).start();
}
}
举例2:
package com.study.thread;
class Parent{
public static int i=10;
public synchronized void downParent(){
i--;
try {
System.out.println("parent:" + i);
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class CongRuSuo1 extends Parent{
public synchronized void downSon(){
while (i>0){
try {
i--;
System.out.println("son:" + i);
Thread.sleep(1000);
super.downParent();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
CongRuSuo1 t1 = new CongRuSuo1();
new Thread(new Runnable() {
@Override
public void run() {
t1.downSon();
}
}).start();
}
}
输出结果
线程中出现错误如何处理,举例如下:
package com.study.thread;
public class SyncException {
private int count=0;
public synchronized void sayCount(){
while (true){
count ++ ;
try {
Thread.sleep(100);
System.out.println(count);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (count==10){
try {
Integer.parseInt("a");
} catch (Exception e){
e.printStackTrace();
System.out.println("log 日志");
continue;
}
}
}
}
public synchronized void method3(){
System.out.println("metho3");
}
public static void main(String[] args) {
SyncException t1 = new SyncException();
new Thread(new Runnable() {
@Override
public void run() {
t1.sayCount();
}
}).start();
}
}
其中任务失败了,线程会继续往下走,一般处理方法是 日志记录下来
字符串不要做锁
synchronized(“abc”) 这样是有问题的 可以改成这样 synchronized(new String(“abc”))
如果字符串做锁,程序中不要修改 这个锁
Person person = new Person();
synchronized(person ) 两个线程 线程A 修改了 person 的name 属性,是不影响 锁的持有的,线程B 还是只有A 结束的时候才能获取到锁