线程安全的问题
线程执行时有随机性
同步代码块
把操作共享数据的代码锁起来
synchronized (锁对象){ //锁对象是唯一的
操作共享数据的代码
}
package multithread.synchronize;
public class ThreadDemo {
public static void main(String[] args) {
SynchronizeThread t1 = new SynchronizeThread();
SynchronizeThread t2 = new SynchronizeThread();
SynchronizeThread t3 = new SynchronizeThread();
t1.setName("1号");
t2.setName("2号");
t3.setName("3号");
t1.start();
t2.start();
t3.start();
}
}
package multithread.synchronize;
public class SynchronizeThread extends Thread{
//表示这个类所有的对象
static int ticket = 0;
//锁对象一定是唯一的
static Object object = new Object();
@Override
public void run() {
while (true){
//同步代码块
//一个文件只有一个类的xxx.class文件
synchronized (SynchronizeThread.class){
if (ticket < 100){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(getName() + "正在卖第" + ticket + "票");
ticket++;
}else {
break;
}
}
}
}
}
特点1: 锁默认打开,有一个线程进去了,锁自动关闭
特点2: 里面的代码全部执行完毕,线程出来,锁自动打开
同步方法
就是把synchronized关键字加到方法上
格式:
修饰符 synchronized 返回值类型 方法名(方法参数) {...}
特点1: 同步方法是锁住方法里面所有的代码
特点2::锁对象不能自己指定
非静态: this
静态:当前类的字节码文件对象
package multithread.SynchronizationMethod;
public class ThreadDemo {
public static void main(String[] args) {
/**
*同步方法
*同步方法就是将方法修饰符改为synchronized的方法
*同步方法会自动锁住当前实例
* 技巧 同步代码块
*/
SynchronizationRunnable mr = new SynchronizationRunnable();
Thread t1 = new Thread(mr);
Thread t2 = new Thread(mr);
Thread t3 = new Thread(mr);
t1.start();
t2.start();
t3.start();
}
}
package multithread.SynchronizationMethod;
public class SynchronizationRunnable implements Runnable{
//因为他只能调用一次就不用加static
int ticket = 0;
@Override
public void run() {
while (true){
if (Method()){
break;
}
}
}
//当前对象
private synchronized boolean Method(){
if (ticket == 100){
return true;
} else {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
ticket++;
System.out.println(Thread.currentThread().getName()+"卖出了第sb"+ticket+"张票");
}
return true;
}
}