线程安全
- 原因:由于一个线程在操作共享数据过程中,未执行完毕的情况下,另外的线程参与进来,导致共享数据存在安全问题
- 解决方式:必须让一个线程操作共享数据完毕之后,其他线程才有机会参与共享数据操作
- java解决线程安全:线程的同步机制
- 同步代码块
synchronized(同步监视器){
//需要被同步的代码块(即为操作共享数据的代码)
}
上篇的代码可改为:
public class testThread{
public static void main(String [] args) {
window window = new window();
Thread thread1 = new Thread(window);
Thread thread2 = new Thread(window);
Thread thread3 = new Thread(window);
thread1.setName("窗口1");
thread2.setName("窗口2");
thread3.setName("窗口3");
thread1.start();
thread2.start();
thread3.start();
}
}
class window implements Runnable{
int tickets = 100;
Object obj= new Object();
@Override
public void run() {
// TODO Auto-generated method stub
while(true){
synchronized (obj) {//同步监视器(锁)可以用任意类的实例来充当
if(tickets>0){
System.out.println(Thread.currentThread().getName()+":卖出第"+tickets+"张票");
tickets=tickets-1;
}
}
}
}
}
public class sellTicket {
public static void main(String [] args){
window window1 = new window();
window window2 = new window();
window window3 = new window();
window1.setName("窗口1");
window2.setName("窗口2");
window3.setName("窗口3");
window1.start();
window2.start();
window3.start();
}
}
class window extends Thread{
public static int tickets = 100;
static Object obj=new Object();//所有线程共用一把锁,此处用static
@Override
public void run() {
while(true){
synchronized (obj) {
if(tickets>0){
System.out.println(Thread.currentThread().getName()+":卖出第"+tickets+"张票");
tickets=tickets-1;
}else{
break;
}
}
}
}
}
注意:锁只能用同一个,所以继承的方式要用static。
- 同步方法
将操作共享数据的方法声明为synchronized,即此方法为同步方法,能够保证当其中一个线程执行此方法时,其他线程在外等待直至此线程执行完此方法。
同步方法的锁,this
public class testThread{
public static void main(String [] args) {
window window = new window();
Thread thread1 = new Thread(window);
Thread thread2 = new Thread(window);
Thread thread3 = new Thread(window);
thread1.setName("窗口1");
thread2.setName("窗口2");
thread3.setName("窗口3");
thread1.start();
thread2.start();
thread3.start();
}
}
class window implements Runnable{
int tickets = 100;
Object obj= new Object();
@Override
public void run() {
// TODO Auto-generated method stub
while(true){
show();
}
}
public synchronized void show() {
synchronized (obj) {
if(tickets>0){
System.out.println(Thread.currentThread().getName()+":卖出第"+tickets+"张票");
tickets=tickets-1;
}
}
}
}