示例程序1.線程中改變lock 對象
/**
* 鎖對象改變的問題
* 變了就沒用了
* */
public class ChangeLock {
/**
* 鎖對象變了,那麼鎖就沒有用了,但若是鎖對象的屬性變了則是不影響鎖的效用
*/
private String lock = "lock";
/**
* 加同步鎖的目的就是要保證原子性,即一個線程執行此方法體開始並結束後,另執另外一個開始結束
*/
private void methgod() {
synchronized(lock) {
System.out.println("當前線程"+Thread.currentThread().getName()+"開始");
/**
* 未加這句話:(保持完整的原子性)
* 當前線程t1開始(等待2000毫秒。。。)
當前線程t1結束(等待100毫秒。。。)
當前線程t2開始(等待2000毫秒。。。)
當前線程t2結束
加了這句話:t1,t2同時開始,等2000同時結束
當前線程t1開始
當前線程t2開始
當前線程t1結束
當前線程t2結束
*/
lock = "lock change";
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("當前線程"+Thread.currentThread().getName()+"結束");
}
}
public static void main(String[] args) {
final ChangeLock cl = new ChangeLock();
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
cl.methgod();
}
},"t1");
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
cl.methgod();
}
},"t2");
t1.start();
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
t2.start();
}
}
示例程序2:死鎖
public class DeadLock extends Thread{
private String lock1 = "lock1";
private String lock2 = "lock2";
private String tag;
public String getTag() {
return tag;
}
public void setTag(String tag) {
this.tag = tag;
}
@Override
public void run() {
if(tag.equals("a")){
synchronized (lock1) {
System.out.println("當前線程"+Thread.currentThread().getName()+"進入lock1執行");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (lock2) {
System.out.println("當前線程"+Thread.currentThread().getName()+"進入lock2執行");
}
}
}
if(tag.equals("b")){
synchronized (lock2) {
System.out.println("當前線程"+Thread.currentThread().getName()+"進入lock2執行");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (lock1) {
System.out.println("當前線程"+Thread.currentThread().getName()+"進入lock1執行");
}
}
}
}
public static void main(String[] args) {
DeadLock dl1 = new DeadLock();
dl1.setTag("a");
dl1.start();
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
DeadLock dl2 = new DeadLock();
dl2.setTag("b");
dl2.start();
}
}
示例程序3 :不改變lock對象,改變lock對象屬性值,不會產生線程安全問題
public class ModifyLock {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public synchronized void changeAttri(String name, int age) {
System.out.println("當前線程"+Thread.currentThread().getName()+"開始");
this.setAge(age);
this.setName(name);
System.out.println("當前線程"+Thread.currentThread().getName()+"修改內容爲:"+ name+":"+age);
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("當前線程"+Thread.currentThread().getName()+"結束");
}
public static void main(String[] args) {
final ModifyLock cl = new ModifyLock();
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
cl.changeAttri("aaa",2);
}
},"t1");
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
cl.changeAttri("bbb",3);
}
},"t2");
t1.start();
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
t2.start();
}
}
示例程序4:鎖的種類
public class ObjectLock {
public void method1(){
synchronized (this) {//對象鎖
try {
System.out.println("method1......");
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void method2(){
synchronized (ObjectLock.class) {//類鎖
try {
System.out.println("method2......");
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
private Object lock = new Object();
public void method3(){
synchronized (lock) {//任何對象鎖
try {
System.out.println("method3......");
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
final ObjectLock ol = new ObjectLock();
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
ol.method1();
}
},"t1");
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
ol.method2();
}
},"t2");
Thread t3 = new Thread(new Runnable() {
@Override
public void run() {
ol.method3();
}
},"t3");
t1.start();
t2.start();
t3.start();
}
}
示例程序5:String對象鎖
public class StringLock {
public void method() {
//如果鎖是非new出來的,那麼就是一個常量,則被獨佔while(true)死循環,,若是被new出來的,則2個對象
/**
* 當前線程t2開始
當前線程t1開始
當前線程t1結束
當前線程t2結束
*/
// synchronized (new String("字符串常量")) {
/**
* 當前線程t1開始
當前線程t1結束
當前線程t1開始
當前線程t1結束
*/
synchronized ("字符串常量") {
try {
while(true) {
System.out.println("當前線程"+Thread.currentThread().getName()+"開始");
Thread.sleep(2000);
System.out.println("當前線程"+Thread.currentThread().getName()+"結束");
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
final StringLock ol = new StringLock();
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
ol.method();
}
},"t1");
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
ol.method();
}
},"t2");
t1.start();
t2.start();
}
}