1.同步代码块
实现方法一:实现Runnable接口
package com.dm.java;
**
*
* 1.问题:卖票过程中出现重票或者错票的问题----->出现了线程的安全问题
* 2.问题出现的原因:当某个线程操作车票的过程中,尚未操作完成时,其它线程参与进来,也操作车票
* 3.如何解决:当一个线程在操作ticket的时候,其它线程不能参与进来。直到当前线程操作完ticket时,其它线程才能开始操作
* 这种情况即时当前线程出现了阻塞,也不能被改变
* 4.在JAVA中,通过同步机制,来解决线程的安全问题
*
* 方式一:同步代码块
*
* synchronized(同步监视器){
* //需要被同步的代码
* }
* 说明:1.操作共享数据的代码,即为需要被同步的代码。---->不能包含多了,也不能包含代码少了。
* 2. 共享数据:多个线程共同操作的变量。比如当前代码的ticket
* 3.同步监视器:俗称:锁。任何一个类的对象,都可以充当锁。
* 要求:多个线程必须要共用通一把锁。
* 补充:在实现Runnable接口创建多线程的方式中,可以考虑用this充当同步监视器。
*
* 方式二:同步方法(见下一章)
*
*
* @author JessieWu
* @create 2020-07-27 15:28
*/
class Window implements Runnable{
private int ticket = 100;
Object obj = new Object();
@Override
public void run() {
while (true){
synchronized (obj) {//synchronized (this)这样也是可以的
if (ticket > 0) {
System.out.println(Thread.currentThread().getName() + ":卖票,票号为:" + ticket);
ticket--;
} else {
break;
}
}
}
}
}
public class WindowTest {
public static void main(String[] args) {
Window w = new Window();
Thread t1 = new Thread(w);
Thread t2 = new Thread(w);
Thread t3 = new Thread(w);
t1.setName("窗口一");
t2.setName("窗口二");
t3.setName("窗口三");
t1.start();
t2.start();
t3.start();
}
}
实现方二:实现Thread类继承
package com.dm.java;
/** 继承的方式
*
* 在继承Thread类创建多线程的方式中,慎用this充当同步监视器。考虑使用当前类充当监视器
* @author JessieWu
* @create 2020-07-27 16:24
*/
class MyThread extends Thread{
static Object obj = new Object();
private static int ticket = 100;
@Override
public void run() {
while (true){
synchronized (obj){ //synchronized (Windows.class)这样也是可以的
if (ticket > 0) {
System.out.println(Thread.currentThread().getName() + ":卖票,票号为" + ticket);
ticket--;
} else {
break;
}
}
}
}
}
public class WindowTest1 {
public static void main(String[] args) {
MyThread t1 = new MyThread();
MyThread t2 = new MyThread();
MyThread t3 = new MyThread();
t1.setName("窗口一");
t2.setName("窗口二");
t3.setName("窗口三");
t1.start();
t2.start();
t3.start();
}
}
网友评论