1)在java语言中,引入了对象互斥锁的概念,保证共享数据操作的完整性。每个对象都对应于一个可称为“互斥锁”的标记,这个标记保证在任一时刻,只能有一个线程访问对象
2)关键字synchronized来与对象的互斥锁联系。当某个对象synchronized修饰时,表明该对象在任一时刻只能由一个线程访问
死锁:两个或两个以上的进程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去
其他线程可以自由访问非同步方法,并且可能对同步方法产生影响;加了同步效率可能降低,不加同步可能产生数据不一致
2)关键字synchronized来与对象的互斥锁联系。当某个对象synchronized修饰时,表明该对象在任一时刻只能由一个线程访问
public class TestSync implements Runnable { // 实现Runnable接口,要实现run()方法,是一个线程类
Timer timer = new Timer();
public static void main(String[] args) {
TestSync test = new TestSync();
Thread t1 = new Thread(test); // 启动线程t1
Thread t2 = new Thread(test); // new线程
t1.setName("t1");
t2.setName("t2");
t1.start();
t2.start();
}
public void run() {
timer.add(Thread.currentThread().getName());
}
}
class Timer {
private static int num = 0;
public synchronized void add(String name) { //执行该段代码时,锁定当前对象
num++;
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
}
System.out.println(name + ", 你是第" + num + "个使用timer的线程");
}
/*public void add(String name) {
synchronized (this) { //锁定当前对象(this)
num++;
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
}
System.out.println(name + ", 你是第" + num + "个使用timer的线程");
}
}*/
}死锁:两个或两个以上的进程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去
public class TestDeadLock implements Runnable {
public int flag = 1; //成员变量
static Object o1 = new Object(), o2 = new Object();
public void run() {
System.out.println("flag=" + flag);
if (flag == 1) {
synchronized (o1) { //锁住01,等待资源
try {
Thread.sleep(500);
} catch (Exception e) {
e.printStackTrace();
}
synchronized (o2) { //锁住02,等02
System.out.println("1");
}
}
}
if (flag == 0) {
synchronized (o2) { //锁住02,等02
try {
Thread.sleep(500);
} catch (Exception e) {
e.printStackTrace();
}
synchronized (o1) { //锁住01
System.out.println("0");
}
}
}
}
public static void main(String[] args) {
TestDeadLock td1 = new TestDeadLock();
TestDeadLock td2 = new TestDeadLock();
td1.flag = 1;
td2.flag = 0;
Thread t1 = new Thread(td1);
Thread t2 = new Thread(td2);
t1.start();
t2.start();
}
}其他线程可以自由访问非同步方法,并且可能对同步方法产生影响;加了同步效率可能降低,不加同步可能产生数据不一致
public class TT implements Runnable {
int b = 100;
//该方法锁定当前线程对象只针对本段代码,其他线程可以执行其他未被锁定方法,不能访问同步方法
public synchronized void m1() throws Exception {
b = 1000;
Thread.sleep(5000);
System.out.println("b = " + b);
}
public void m2() throws Exception {
System.out.println(b);
}
public void run() {
try {
m1();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) throws Exception {
TT tt = new TT();
Thread t = new Thread(tt);
t.start();
Thread.sleep(1000);
tt.m2();
}
}
/* 1000 //当子线程访问m1()方法时被锁定,b被改为1000,睡眠5秒,当子线程被锁定时,主线程继续执行访问m2()方法
* b = 1000 //睡眠结束后继续子线程执行m1()方法
*/public class TT implements Runnable {
int b = 100;
public synchronized void m1() throws Exception {
// Thread.sleep(2000);
b = 1000;
Thread.sleep(5000);
System.out.println("b = " + b);
}
public void m2() throws Exception {
Thread.sleep(2500);
b = 2000;
}
public void run() {
try {
m1();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) throws Exception {
TT tt = new TT();
Thread t = new Thread(tt);
t.start();
tt.m2();
System.out.println(tt.b);
}
}
/* 2000 //当子线程访问m1()方法时被锁定,b被改为1000,睡眠5秒,当子线程被锁定时,主线程继续执行访问m2()方法,此时b被该为2000
b = 2000 //睡眠结束后继续子线程执行m1()方法,此时b已经被m2()改为2000
*/
public class TT implements Runnable {
int b = 100;
//该方法锁定当前线程对象只针对本段代码,其他线程可以执行其他未被锁定方法,不能访问同步方法
public synchronized void m1() throws Exception {
// Thread.sleep(2000);
b = 1000;
Thread.sleep(5000);
System.out.println("b = " + b);
}
public synchronized void m2() throws Exception {
Thread.sleep(2500);
b = 2000;
}
public void run() {
try {
m1();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) throws Exception { //首先执行main()方法
TT tt = new TT();
Thread t = new Thread(tt);
t.start(); //开始执行子线程,执行run(),即m1()方法
tt.m2(); //main()方法继续向下执行,执行m2()方法
//等m2()方法执行结束后再执行m1()方法
System.out.println(tt.b);//等m1()睡眠时打印
}
}
/* //m1()执行,则m2()不能执行 *
* 1000 //执行主线程
* b = 1000 //执行t线程
*/
3618

被折叠的 条评论
为什么被折叠?



