1.多线程共享数据:在多线程中,多个线程k可能同时处理同一个资源,这就是在多线程中的共享数据
2.线程同步
- 解决数据共享问题,必须使用同步,所谓同步就是指多个线程在同一个时间段只能有一个线程执行指定代码,其他线程要等待此线程完成之后才可以继续执行。
- 线程进行同步,有以下三种方法:
- (1)同步代码块
- synchronized(要同步的对象){要同步的操作}
- (2)同步方法
- public synchronized void method(){}
- (3)Lock(ReentrantLock)(更灵活的代码控制)
- 多线程共享数据,会有安全问题,使用同步可以解决安全问题,但同时会牺牲性能,所以同步的代码块尽量保持简短,把不随数据变化的相关代码移除同步块,不要阻塞。
3.同步准则 - 当编写synchronized块时,有几个简单的准则可以遵循,这些准则在避免死锁和性能危险的风险方面有很大帮助
- (1)使代码块保持简短,把不随线程变化的预处理和后处理移除synchronized 块
- (2)不要阻塞,如inputStream.read()。
- (3)不保持锁的时候,不要对其它对象调用方法。
import java.util.concurrent.locks.ReentrantLock;
/**
* 1.多线程共享数据:
* 在多线程中,多个线程k可能同时处理同一个资源,这就是在多线程中的共享数据
* 2.线程同步
* 解决数据共享问题,必须使用同步,所谓同步就是指多个线程在同一个时间段只能有一个线程执行指定代码,
* 其他线程要等待此线程完成之后才可以继续执行。
* 线程进行同步,有以下三种方法:
* (1)同步代码块
* synchronized(要同步的对象){要同步的操作}
* (2)同步方法
* public synchronized void method(){}
* (3)Lock(ReentrantLock)(更灵活的代码控制)
* 多线程共享数据,会有安全问题,使用同步可以解决安全问题,但同时会牺牲性能,所以同步的代码块尽量保持简短,
* 把不随数据变化的相关代码移除同步块,不要阻塞。
*
* 3.同步准则
* 当编写synchronized块时,有几个简单的准则可以遵循,这些准则在避免死锁和性能危险的风险方面有很大帮助
* (1)使代码块保持简短,把不随线程变化的预处理和后处理移除synchronized 块
* (2)不要阻塞,如inputStream.read()。
* (3)不保持锁的时候,不要对其它对象调用方法。
*
*/
public class ThreadDeno4 {
public static void main(String[] args) {
MyRunnable4 mr4=new MyRunnable4();
Thread t1=new Thread(mr4);
Thread t2=new Thread(mr4);
t1.start();
t2.start();
}
}
/**
* 1.多线程同享数据是,会发生线程不安全的情况
* 2.多线程共享数据必须使用同步
* 3
*/
class MyRunnable4 implements Runnable{
private int ticket=10;
private Object obj=new Object(); //同步锁
@Override
public void run() {
for (int i = 0; i < 300; i++) {
// if(ticket>0) {
//第一种方式
// synchronized (obj) {
// ticket--;
// try {
// Thread.sleep(1000);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
// System.out.println("您购买的票剩余" + ticket + "张");
// }
// }
// method();
method2();
}
}
//第二种方式,synchronized同步方法
private synchronized void method(){
if(ticket>0) {
ticket--;
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("您购买的票剩余" + ticket + "张");
}
}
ReentrantLock lock=new ReentrantLock();//锁
private void method2(){
lock.lock();
try {
if(ticket>0) {
ticket--;
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("您购买的票剩余" + ticket + "张");
}
}finally {
lock.unlock();//释放锁
}
}
}