线程安全解决方式
-
- 同步代码块
(1)操作共享数据的代码,即为需要被同步的代码;
(2)共享数据:多个线程共享共同操作的变量,比如:ticket就是共享数据(下面代码中的例子)
(3)同步监视器,俗称锁,任何一个类的对象,都可以充当锁;
锁的要求:(多个线程必须公用一个锁,即同一个类的一个对象)
- 同步代码块
通过实现Runnable接口的方式来创建线程:
public class Mythread implements Runnable{
private int ticket = 100;
Object obj = new Object();
@Override
public void run() {
while(true){
synchronized (obj) {
if (ticket > 0) {
System.out.println(Thread.currentThread().getName() + "通过runnable方式开始售票,票号为:" + ticket);
ticket--;
} else {
break;
}
}
}
}
}
通过继承Thread类来创建线程的方式:
public class Myextends extends Thread{
private static int ticket = 100;
public Myextends(String str) {
this.setName(str);
}
/*注意在通过继承Thread时,同步锁需要设置为static的对象*/
private static Object obj = new Object();
@Override
public void run() {
while(true){
synchronized (obj){
if(ticket>0){
System.out.println(Thread.currentThread().getName()+"通过extends方式开始售票,票号为:"+ticket);
ticket--;
}
}
}
}
}
- 同步方法
(1)同步方法任然涉及同步监视器,只是不需要我们显示的声明;
(2)非静态的同步方法,同步监视器是:this;
静态的同步方法,同步监视器是:当前类本身;
public class MyRunnable implements Runnable{
private int ticket = 100;
@Override
public void run() {
while(true){
SynMethod();
}
}
private synchronized void SynMethod(){
if (ticket > 0) {
System.out.println(Thread.currentThread().getName() + "通过runnable方式开始售票,票号为:" + ticket);
ticket--;
}
}
}
public class MyExtends extends Thread{
private static int ticket = 100;
public MyExtends(String str) {
this.setName(str);
}
public void run() {
while(true){
SynMethod();
}
}
public static synchronized void SynMethod(){
if(ticket>0){
System.out.println(Thread.currentThread().getName()+"通过extends方式开始售票,票号为:"+ticket);
ticket--;
}
}
}