提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
提示:这里可以添加本文要记录的大概内容:
lock是JUC里重要的内容,下面是容易出错的问题。记录一下
一、lock问题
代码如下(示例):
i/**
* 锁的问题
* @author 祥哥
*
*/
public class TestLock {
public static void main(String[] args) {
Cat cat = new Cat();
//A线程执行吃
new Thread(new Runnable() {
@Override
public void run() {
cat.eat();
}
},"A").start();
//B线程执行玩
new Thread(new Runnable() {
@Override
public void run() {
cat.play();
}
},"B").start();
}
}
//简单猫的类
class Cat{
public synchronized void eat() {
System.out.println(Thread.currentThread().getName()+ "猫吃鱼");
}
public synchronized void play() {
System.out.println(Thread.currentThread().getName()+"猫玩球");
}
}
请问线程A和线程B那个线程执行?
可以看到结果永远是A线程先执行,在去执行B。这是因为他们锁的是同一个对象,所以一次只能一个线程访问。举个通俗的例子就是:这个对象是一个房间,每一个线程进去然后上锁,所以需要排队一次一个线程的访问。
代码如下(示例):
public class TestLock {
public static void main(String[] args) {
Cat cat1 = new Cat();
Cat cat2 = new Cat();
new Thread(new Runnable() {
@Override
public void run() {
cat1.eat();
}
},"A").start();
new Thread(new Runnable() {
@Override
public void run() {
cat2.play();
}
},"B").start();
}
}
class Cat{
public synchronized void eat() {
try {
//这里睡了1分钟
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+ "猫吃鱼");
}
public synchronized void play() {
System.out.println(Thread.currentThread().getName()+"猫玩球");
}
}
请问线程A和线程B那个线程执行?
因为是两个对象,所以有两个锁。而第一个睡了1分钟,所以第二个就先执行了
/**
* 锁的问题两个对象 变成静态方法
* @author 祥哥
*
*/
public class TestLock {
public static void main(String[] args) {
Cat cat1 = new Cat();
Cat cat2 = new Cat();
new Thread(new Runnable() {
@Override
public void run() {
cat1.eat();
}
},"A").start();
new Thread(new Runnable() {
@Override
public void run() {
cat2.play();
}
},"B").start();
}
}
class Cat{
//这里变成了静态方法
public static synchronized void eat() {
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+ "猫吃鱼");
}
public static synchronized void play() {
System.out.println(Thread.currentThread().getName()+"猫玩球");
}
}
请问线程A和线程B那个线程执行?
因为是静态方法,是虽然是创建了两次,static内存是共享的都在类库里。
/**
* 锁的问题两个对象 变成1个静态方法,1个普通方法
* @author 祥哥
*
*/
public class TestLock {
public static void main(String[] args) {
Cat cat1 = new Cat();
Cat cat2 = new Cat();
new Thread(new Runnable() {
@Override
public void run() {
cat1.eat();
}
},"A").start();
new Thread(new Runnable() {
@Override
public void run() {
cat2.play();
}
},"B").start();
}
}
class Cat{
public static synchronized void eat() {
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+ "猫吃鱼");
}
public synchronized void play() {
System.out.println(Thread.currentThread().getName()+"猫玩球");
}
}
请问线程A和线程B那个线程执行?
两个锁锁的不一样,一个是锁了静态的共享内存,一个是锁了对象。所以算是两个锁。
总结
总之主要就是static是公用一个内存的,所以锁起来就是同一个对象。