通过同步机制解决线程安全问题:
方式一:同步代码块
synchronized(同步监视器){
//同步代码块,需要被同步的代码
}
说明:操作共享数据的代码,即为需要被同步的代码,不能多包含也不能少包含
共享数据:多个线程共同操作的变量,比如ticket就是共享数据
同步监视器:锁,任何一个对象都可以作为锁
要求:多个线程共用同一个锁
5.同步方式解决了线程安全问题,但是每次只能有一个线程执行,相当于单线程
package com.java.Thread;
/**
- @author jack
- @create 2019-07-09 22:00
*/
public class RunnableWindow implements Runnable {
private int ticket = 100;
Object o = new Object() ;
@Override
public void run() {
while (true) {
//this表示当前对象
synchronized (this){
// synchronized (o) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (ticket > 0) {
System.out.println(Thread.currentThread().getName() + “正在买票,票号为:” + ticket);
ticket–;
} else {
break;
}
}
}
}
}
package com.java.Thread;
/**
-
@author jack
-
@create 2019-07-09 19:34
*/
public class Window extends Thread {
private static int ticket =100;
private static Object o = new Object() ;
@Override
public void run() {
while (true) {
//通过反射是用类对象
synchronized (Window.class){// synchronized (this){//这种方式不对,因为三个线程对应三个对象 //synchronized (o) { if (ticket > 0) { System.out.println(getName() + "买票,票号为:" + ticket); ticket--; } else { break; } } }
}
}
方式二:同步方法
如果操作共享数据得方法操作在一个方法中,可以将方法同步
实现Runnable接口:
package com.java.Thread;
/**
-
@author jack
-
@create 2019-07-09 22:00
*/
public class RunnableWindow implements Runnable {
private int ticket = 100;
Object o = new Object() ;
@Override
public void run() {
while (true) {show(); }
}
private synchronized void show(){//同步监视器:this
// synchronized (o) {
//this表示当前对象
//synchronized (this){
if (ticket > 0) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}System.out.println(Thread.currentThread().getName() + "正在买票,票号为:" + ticket); ticket--; }
}
}
继承Thread类
package com.java.Thread;
/**
-
@author jack
-
@create 2019-07-09 19:34
*/
public class Window extends Thread {
private static int ticket =100;
private static Object o = new Object() ;
@Override
public void run() {
while (true) {
show();}
}
public static synchronized void show(){//同步监视器就是当前类
//通过反射是用类对象
//synchronized (Window.class){
//这种方式不对,因为三个线程对应三个对象
// synchronized (this){
//synchronized (o) {
if (ticket > 0) {
System.out.println(Thread.currentThread().getName() + “买票,票号为:” + ticket);
ticket–;
}
}
}
注意:两种实现同步的方式的锁都是一样的,在实现Runnable接口时同步监视器就是当前对象,继承Thread类就是当前类