同步方法解决线程安全问题
如果操作共享数据的代码完整的声明在一个方法中,我们不妨将此方法声明同步的。
同步方法的总结:
1.同步方法仍然涉及到同步监视器,只是不需要我们显式的声明。
2.非静态的同步方法,同步监视器是:this
静态的同步方法,同步监视器是:当前类本身
使用实现Runnable接口创建多线程
package com.klvchen.java;
class Window3 implements Runnable{
private int ticket = 100;
boolean isFlag = true;
@Override
public void run() {
while (isFlag){
show();
}
}
private synchronized void show(){ //同步监视器:this
if (ticket > 0){
try {
Thread.sleep(100);
}catch (InterruptedException e){
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + ":卖票,票号为:" + ticket);
ticket--;
}else {
isFlag = false;
}
}
}
public class WindowTest3 {
public static void main(String[] args) {
Window3 w = new Window3();
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();
}
}
使用继承Thread类创建多线程
package com.klvchen.java;
class Window4 extends Thread{
private static int ticket = 100;
private static boolean isFlag = true;
@Override
public void run() {
while (isFlag){
show();
}
}
private static synchronized void show(){//同步监视器: Window4.class
//private synchronized void show(){ //同步监视器: t1,t2,t3,此种解决方式不正确
if (ticket > 0){
try {
Thread.sleep(100);
}catch (InterruptedException e){
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + ": 卖票, 票号为: " + ticket);
ticket--;
}else {
isFlag = false;
}
}
}
public class WindowTest4 {
public static void main(String[] args) {
Window4 t1 = new Window4();
Window4 t2 = new Window4();
Window4 t3 = new Window4();
t1.setName("窗口1");
t2.setName("窗口2");
t3.setName("窗口3");
t1.start();
t2.start();
t3.start();
}
}