java实现多线程安全使用的线程的同步机制
* -- 方式一:同步代码块
* ①.语法:synchronized(同步监视器){
* 需要同步的代码块(共享的数据代码)
* }
* ②.共享数据:多个线程共同操作的同一个数据或者资源(成员变量或者类变量)
* ③.同步监视器(锁):通常使用一个对象(任何对象)来充当,哪个线程获取此监视器,就可以执行同步代码(要求所有的线程共用一把锁)
* -- 方式二:同步方法
①.语法:将操作共享数据的方法声明成synchronized
* eg:public void synchronized 方法名(){}
* ②.特点:保证当执行一个子线程执行到此方法时,其他子线程排队等候直到该线程执行完方法。
1.方法—:同步代码块
注意:
如果使用继承的方式创建多线程
不能使用this充当同步监视器,因为this代表不同的对象
class Window3 extends Thread{
// 总票数
static int ticket = 100;
// 只创建一次
static Object obj = new Object();
@Override
public void run() {
while (true) {
// this代表当前对象 window2 同步监视器
synchronized (obj) {
if (ticket > 0) {
// 打印票号,并且维护计数器
System.out.println(Thread.currentThread().getName()+"售票,票号:"+ticket --);
}else {
// 票已抢完
break;
}
}
}
}
}
public class TestWindow3 {
public static void main(String[] args) {
Window3 w1 = new Window3();
Window3 w2 = new Window3();
Window3 w3 = new Window3();
w1.setName("窗口1");
w2.setName("窗口2");
w3.setName("窗口3");
w1.start();
w2.start();
w3.start();
}
}
使用实现的方式来实现
class Window2 implements Runnable{
int ticket = 100;
@Override
public void run() {
while (true) {
// this代表当前对象 window2 同步监视器
synchronized (this) {
if (ticket > 0) {
// 打印票号,并且维护计数器
System.out.println(Thread.currentThread().getName()+"售票,票号:"+ticket --);
}else {
// 票已抢完
break;
}
}
}
}
}
public class TestWindow2 {
public static void main(String[] args) {
Window2 p = new Window2();
Thread t1 = new Thread(p);
Thread t2 = new Thread(p);
Thread t3 = new Thread(p);
t1.setName("窗口1");
t2.setName("窗口2");
t3.setName("窗口3");
t1.start();
t2.start();
t3.start();
}
}
2.方法二:同步方法
class Window4 implements Runnable{
int ticket = 100;
@Override
public void run() {
while (true) {
// 调用同步方法
print();
}
}
/**
* 同步方法
*/
private synchronized void print() {
if (ticket > 0) {
// 打印票号,并且维护计数器
System.out.println(Thread.currentThread().getName()+"售票,票号:"+ticket --);
}else {
// 票已抢完
return;
}
}
}
public class TestWindow4 {
public static void main(String[] args) {
Window2 p = new Window2();
Thread t1 = new Thread(p);
Thread t2 = new Thread(p);
Thread t3 = new Thread(p);
t1.setName("窗口1");
t2.setName("窗口2");
t3.setName("窗口3");
t1.start();
t2.start();
t3.start();
}
}