public class test1 { public static void main(String[] args) { myThread m1 = new myThread(1); myThread m2 = new myThread(2); new Thread(m1).start(); new Thread(m2).start(); } } class myThread implements Runnable{ static Object o = new Object(); static int i = 1; int k; myThread(int k){ this.k = k; } synchronized public void run() { while(i <= 100){ System.out.println(k + "线程:" + i); i++; } } } 那如果这样呢?锁定了m1,想要锁定m2的时候但是不能访问o,所以锁定m1的时候m2应该拿不到锁吧?
Java code ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 public class test1 { public static void main(String[] args) { myThread m1 = new myThread(1); myThread m2 = new myThread(2); new Thread(m1).start(); new Thread(m2).start(); } } class myThread implements Runnable{ static Object o = new Object(); static int i = 1; int k; myThread(int k){ this.k = k; } synchronized public void run() { while(i <= 100){ System.out.println(k + "线程:" + i); i++; } } }那如果这样呢?锁定了m1,想要锁定m2的时候但是不能访问o,所以锁定m1的时候m2应该拿不到锁吧?
1. 要执行synchronized声明的方法,必须要获得该方法所属的对象的锁。class MyHandler implements Runnable{ int i = 0; public synchronized void run() { // 需要获得MyHandler的某个实例的锁,才能进入这个方法 i++; System.out.println(i); } }可以这么理解,就是把synchronized声明的方法(不一定是run方法,还可以是其他的)想象为一个房间(资源),如果有2个人(线程)都想进去,那么必须要有这个房间的钥匙(获得资源,并关上房门,即加锁)。如果1个人进去了,锁上了门,那么另外一个人就只能等待。 MyHandler h1 = new MyHandler(); Thread t1 = new Thread(h1); Thread t2 = new Thread(h1); t1.start(); // t1可能获得了h1这个资源,并加了锁 t2.start(); // t2 可能就只能等待了,因为他没有获得h1这个资源,无法加锁(锁门) 区别MyHandler h1 = new MyHandler(); MyHandler h2 = new MyHandler(); Thread t1 = new Thread(h1); Thread t2 = new Thread(h2); t1.start(); // t1可能获得了h1这个资源,并加了锁 t2.start(); // t2 也可能获得了h2这个资源,并加了锁(因为h1和h2是两个资源,互相独立,所以t1和t2都可以各玩儿各的)2. 同步块其实也是相同的概念,不过比synchronized方法灵活一点(可以对任意的资源,不一定是拥有synchronized方法本身的这个对象)class Foo{}class MyHandler implements Runnable{ Foo foo = new Foo(); int i = 0; public void run() { synchronized(foo){ // 需要获得foo这个实例的锁,才能进入synchronized块,执行i++这个操作 i++; } System.out.println(i); } } 3. 使用java concurrent api,加锁更好(高大上)class MyHandler{ private static Lock lock = new ReentrantLock(); private int i = 0;
public static void main(String[] args) {
myThread m1 = new myThread(1);
myThread m2 = new myThread(2);
new Thread(m1).start();
new Thread(m2).start();
}
}
class myThread implements Runnable{
static Object o = new Object();
static int i = 1;
int k;
myThread(int k){
this.k = k;
}
synchronized public void run() {
while(i <= 100){
System.out.println(k + "线程:" + i);
i++;
}
}
}
那如果这样呢?锁定了m1,想要锁定m2的时候但是不能访问o,所以锁定m1的时候m2应该拿不到锁吧?
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class test1 {
public static void main(String[] args) {
myThread m1 = new myThread(1);
myThread m2 = new myThread(2);
new Thread(m1).start();
new Thread(m2).start();
}
}
class myThread implements Runnable{
static Object o = new Object();
static int i = 1;
int k;
myThread(int k){
this.k = k;
}
synchronized public void run() {
while(i <= 100){
System.out.println(k + "线程:" + i);
i++;
}
}
}那如果这样呢?锁定了m1,想要锁定m2的时候但是不能访问o,所以锁定m1的时候m2应该拿不到锁吧?
int i = 0;
public synchronized void run() { // 需要获得MyHandler的某个实例的锁,才能进入这个方法
i++;
System.out.println(i);
}
}可以这么理解,就是把synchronized声明的方法(不一定是run方法,还可以是其他的)想象为一个房间(资源),如果有2个人(线程)都想进去,那么必须要有这个房间的钥匙(获得资源,并关上房门,即加锁)。如果1个人进去了,锁上了门,那么另外一个人就只能等待。
MyHandler h1 = new MyHandler();
Thread t1 = new Thread(h1);
Thread t2 = new Thread(h1);
t1.start(); // t1可能获得了h1这个资源,并加了锁
t2.start(); // t2 可能就只能等待了,因为他没有获得h1这个资源,无法加锁(锁门)
区别MyHandler h1 = new MyHandler();
MyHandler h2 = new MyHandler();
Thread t1 = new Thread(h1);
Thread t2 = new Thread(h2);
t1.start(); // t1可能获得了h1这个资源,并加了锁
t2.start(); // t2 也可能获得了h2这个资源,并加了锁(因为h1和h2是两个资源,互相独立,所以t1和t2都可以各玩儿各的)2. 同步块其实也是相同的概念,不过比synchronized方法灵活一点(可以对任意的资源,不一定是拥有synchronized方法本身的这个对象)class Foo{}class MyHandler implements Runnable{
Foo foo = new Foo();
int i = 0;
public void run() {
synchronized(foo){ // 需要获得foo这个实例的锁,才能进入synchronized块,执行i++这个操作
i++;
}
System.out.println(i);
}
}
3. 使用java concurrent api,加锁更好(高大上)class MyHandler{
private static Lock lock = new ReentrantLock();
private int i = 0;
public void hello(){
lock.lock(); // 加锁,不再使用笨拙的synchronized
try{
i++;
System.out.println(i);
} finally{
lock.unlock(); // 释放锁
}
}
}
楼主没发现自己这句话:第一个线程执行的时候锁定了m1,第二个线程应该拿不到m2的锁了吧.
已经语无伦次了么
锁定了m1,是肯定拿不到m1的啊