卖票案例:
如果不处理,显然会存在同步问题
public class WindowsTest1 {
public static void main(String[] args) {
Windows w = new Windows();
Thread t1 = new Thread(w);
Thread t2 = new Thread(w);
Thread t3 = new Thread(w);
t1.setName("窗口1");
t2.setName("窗口2");
t3.setName("窗口3");
t1.start();
t2.start();
t3.start();
}
}
同步代码块解决并发问题
public class Windows implements Runnable {
private static int ticket = 100;
private static Object obj = new Object();
@Override
public void run() {
while (true) {
// synchronized (this) 是错误的,因为这里的this是具体对象t1 t2 t3
synchronized (Windows.class) {
if (ticket > 0) {
System.out.println(Thread.currentThread().getName() + ":卖票,票号为: " + ticket);
ticket--;
} else {
break;
}
}
}
}
}
同步方法
public class WindowsTest1 {
public static void main(String[] args) {
Windows4 w1 = new Windows4();
Windows4 w2 = new Windows4();
Windows4 w3 = new Windows4();
w1.setName("窗口1");
w2.setName("窗口2");
w3.setName("窗口3");
w1.start();
w2.start();
w3.start();
}
}
线程:
public class Windows4 extends Thread {
private static int ticket = 100;
private static Object obj = new Object();
@Override
public void run() {
while (true) {
show();
}
}
private synchronized static void show() {
//private synchronized void show(){//同步监视器:this w1,w2,w3,此种解决方式是错误的
if (ticket > 0) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + ":卖票,票号为:" + ticket);
ticket--;
}
}
}
不加static,this就会是t1 t2 t3,起不到同步方法的作用
但如果windows是实现Runnable:
public class Windows implements Runnable {
private int ticket = 100;
@Override
public void run() {
while (true) {
show();
}
}
public synchronized void show() { //同步监视器:this,由于是thread封装windows3,所以this都是windows3
// synchronized (this){
if (ticket > 0) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + ":卖票,票号为: " + ticket);
ticket--;
}
// }
}
}
此时的执行main方法:
由于是thread封装w,所以this都是w,不加static仍可以同步
public class WindowsTest1 {
public static void main(String[] args) {
Windows w = new Windows();
Thread t1 = new Thread(w);
Thread t2 = new Thread(w);
Thread t3 = new Thread(w);
t1.setName("窗口1");
t2.setName("窗口2");
t3.setName("窗口3");
t1.start();
t2.start();
t3.start();
}
}