一:同步
我们知道,通过实现Runnable接口的方式进行多线程,可以实现资源共享,但是会出现一个问题,如下所示:
范例1:
package haizhu.com;
class MyThread implements Runnable{
private int ticket = 5;
public void run(){
for(int i =0;i<100;i++){
if(ticket>0){
try{
Thread.sleep(1000); //调用这个方法的线程休眠30毫秒,使用的是Thread,不是具体的线程名称
}catch(InterruptedException e){
e.printStackTrace();
}
System.out.println("卖第 " + ticket-- +" 张票");
}
}
}
}
public class MyThreadDemo {
public static void main(String args[]){
MyThread my = new MyThread();
Thread t1 = new Thread(my);
Thread t2 = new Thread(my);
Thread t3 = new Thread(my);
t1.start();
t2.start();
t3.start();
}
}
结果:
卖第 5 张票
卖第 4 张票
卖第 3 张票
卖第 2 张票
卖第 1 张票
卖第 0 张票
卖第 -1 张票
也就是,在有延迟的情况下,可能出现卖的票为负数的情况。为了解决这个问题,就需要同步的应用。
同步有两种方式,同步代码块和同步方法,使用的是 sychronized 关键字。
范例2:同步代码块
package haizhu.com;
class MyThread implements Runnable{
private int ticket = 5;
public void run(){
for(int i =0;i<100;i++){
synchronized(this){
if(ticket>0){
try{
Thread.sleep(1000);
}catch(InterruptedException e){
e.printStackTrace();
}
System.out.println("卖第 " + ticket-- +" 张票");
}
}
}
}
}
public class MyThreadDemo {
public static void main(String args[]){
MyThread my = new MyThread();
Thread t1 = new Thread(my);
Thread t2 = new Thread(my);
Thread t3 = new Thread(my);
t1.start();
t2.start();
t3.start();
}
}
范例3:同步方法
package haizhu.com;
class MyThread implements Runnable{
private int ticket = 5;
public synchronized void run(){
for(int i =0;i<100;i++){
if(ticket>0){
try{
Thread.sleep(1000);
}catch(InterruptedException e){
e.printStackTrace();
}
System.out.println("卖第 " + ticket-- +" 张票");
}
}
}
}
public class MyThreadDemo {
public static void main(String args[]){
MyThread my = new MyThread();
Thread t1 = new Thread(my);
Thread t2 = new Thread(my);
Thread t3 = new Thread(my);
t1.start();
t2.start();
t3.start();
}
}
二:死锁
同步能够解决卖票为负数的问题,但是也可能带来另外一种问题:死锁
范例3: