多线程并发执行可以提高效率, 但是当多个线程同时去访问同一个资源时, 也会造成安全风险, 这就是线程的安全问题: 多个线程同时访问一个资源。
要先解决这个问题, 必须得保证公共资源在任何时刻只能有一个线程访问。
为了实现这种限制, Java中提供了同步机制, 当多个线程使用同一个共享资源时, 可以将共享西苑代码块放置到一个代码块中, 使用synchronized 关键字来修饰, 被称作同步代码块。其语法格式如下:
synchronized(lock){
... }
lock是一个锁对象, 是同步代码块的关键, 默认为1, 当执行后置0. 当标志位为0 时, 新线程执行到此段代码块时发送阻塞, 知道标志位为1 才能继续运行。
public class Ticket1 implements Runnable{
private int tickets = 10;
Object lock = new Object(); //定义任意一个对象, 用作头同步代码块
@Override
public void run() {
// TODO Auto-generated method stub
while(true) {
synchronized(lock) {
try {
Thread.sleep(100);
}catch (Exception e) {
e.printStackTrace();
// TODO: handle exception
}
if(tickets > 0) {
System.out.println(Thread.currentThread().getName() + "---卖出的票" + tickets--);
}else {
break;
}
}
}
}
}
public class Ex11 {
public static void main(String[] args) {
Ticket1 t = new Ticket1();
new Thread(t, "线程1").start();
new Thread(t, "线程2").start();
new Thread(t, "线程3").start();
new Thread(t, "线程4").start();
}
}
结果:
线程1---卖出的票10
线程1---卖出的票9
线程1---卖出的票8
线程1---卖出的票7
线程1---卖出的票6
线程1---卖出的票5
线程1---卖出的票4
线程1---卖出的票3
线程1---卖出的票2
线程1---卖出的票1
被
synchronized 关键字修饰的方法, 被称为同步方法 它能实现与同步代码块同样的效果。