单任务多线程 安全
线程状态

线程安全
如果有多个线程在同时运行,而这些线程可能会同时运行这段代码。程序每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的,就是线程安全的
买票例子
原理图:

代码:
package com.oracle.Demo03;
public class Tickets implements Runnable{
//把线程的共享数据做成成员变量
private int tickets=100;
//锁对象
private Object mutex=new Object();
public void run() {
while(true){
//同步代码快解决线程安全问题
synchronized (mutex) {
if (tickets>0) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"售出第"+
tickets--+"张票");
}
}
}
}
}
package com.oracle.Demo03;
public class Demo01 {
public static void main(String[] args) {
//创建创建线程任务
Tickets03 t=new Tickets03();
//创建3个线程对象
Thread t1=new Thread(t);
Thread t2=new Thread(t);
Thread t3=new Thread(t);
//开启线程
t1.start();
t2.start();
t3.start();
}
不安全原理图

线程同步(线程安全处理Synchronized)
线程同步的方式有两种:
方式1:同步代码块
方式2:同步方法
同步代码块: 在代码块声明上 加上synchronized
同步代码块中的锁对象可以是任意的对象;但多个线程时,要使用同一个锁对象才能够保证线程安全。
public class Ticket implements Runnable {
//共100票
int ticket = 100;
//定义锁对象
Object lock = new Object();
@Override
public void run() {
//模拟卖票
while(true){
//同步代码块
synchronized (lock){
if (ticket > 0) {
//模拟电影选坐的操作
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "正在卖票:" + ticket--);
}
}
}
}
同步方法
同步方法:在方法声明上加上synchronized
同步方法中的锁对象是 this
package com.oracle.Demo03;
public class Tickets02 implements Runnable {
// 把线程的共享数据做成成员变量
private int tickets = 100;
public void run() {
while (true) {
sale();
}
}
//同步方法
//StringBuffer 慢 所有方法都是同步方法 安全
//StringBuilder 快 所有方法都是非同步方法 不安全
public synchronized void sale(){
if (tickets > 0) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "售出第" + tickets-- + "张票");
}
}
}
package com.oracle.Demo03;
public class Demo01 {
public static void main(String[] args) {
//创建创建线程任务
Tickets03 t=new Tickets03();
//创建3个线程对象
Thread t1=new Thread(t);
Thread t2=new Thread(t);
Thread t3=new Thread(t);
//开启线程
t1.start();
t2.start();
t3.start();
}
}
注意:StringBuffer 慢 所有方法都是同步方法 安全
StringBuilder 快 所有方法都是非同步方法 不安全
Lock接口
Lock提供了一个更加面对对象的锁,在该锁中提供了更多的操作锁的功能
package com.oracle.Demo03;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Tickets03 implements Runnable{
//把线程的共享数据做成成员变量
private int tickets=100;
private Lock lock=new ReentrantLock();
private Object mutex=new Object();
public void run() {
while(true){
lock.lock();
if (tickets>0) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"售出第"+
tickets--+"张票");
lock.unlock();
}
}
}
}
浙公网安备 33010602011771号