定义:
- 在多线程编程,一些敏感的数据不允许被多个线程同时访问,此时就使用同步访问技术,保证数据在任何时刻,最多只有一个线程访问,以保护数据的完整性。
- 线程同步,就是当有一个线程对内存进行 *** 作时,其他线程都不可以对这个内存地址进行 *** 作,直到该线程完成 *** 作,其他线程才能对该内存地址进行 *** 作。
同步具体方法-Synchronized:
- 同步代码块
synchronized(对象){//得到对象的锁,才能 *** 作同步代码块
//需被同步的代码
} - synchronized还可以放在方法声明中,表示整个方法-为同步方法
public synchronized void m(String name){
//需被同步的代码
}
作业1要求:
- 在main方法中启动两个线程
- 第一个线程循环随机打印100以内的整数
- 第二个进程从键盘读取了”Q“命令
package com.yuanhuajun.Homework;
import java.util.Scanner;
/**
* @author Yhj
* @date 2022/4/29 8:44
* @project chapter17
*/
public class Homework01 {
public static void main(String[] args) {
T1 t1 = new T1();
//这是将t1对象传到t2中,用以在t2进程中控制t1;如果用类变量来控制,不需要这样。
T2 t2 = new T2(t1);
Thread thread = new Thread(t2);
//启动两个进程
t1.start();
thread.start();
}
}
class T1 extends Thread {
static Boolean flag = true;
public static Boolean getFlag() {
return flag;
}
public static void setFlag(Boolean flag) {
T1.flag = flag;
}
@Override
public void run() {
while (flag) {
System.out.println("T1线程随机打印:" + (int) (Math.random() * 100+ 1));
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//如果是通过守护进程来控制,这一句无法输出,因为T2结束后,T1直接无条件结束,不会再给时间它输出这一句
//但是如果是通过控制flag,会输出
System.out.println("T1线程退出!");
}
}
class T2 implements Runnable {
private T1 t1;
//守护进程
public T2(T1 t1) {
this.t1 = t1;
//方法一,设置守护进程,当目前进程(t2)结束,t1也立刻结束
t1.setDaemon(true);
}
@Override
public void run() {
String x;
do {
Scanner scanner = new Scanner(System.in);
x = scanner.next();
} while (!(x.equals("Q")));
System.out.println("T2线程退出!");
//方法二:通过类变量控制
// T1.setFlag(false);
}
}
作业2要求:
- 有2个用户分别从同一个卡上取钱(总额10000)
- 每次都取出1000,余额不足时,就不能取款
- 不能出现超取现象
package com.yuanhuajun.Homework;
/**
* @author Yhj
* @date 2022/4/29 10:03
* @project chapter17
*/
public class Homework02 {
public static void main(String[] args) {
Withdraw withdraw = new Withdraw();
Thread thread1 = new Thread(withdraw);
Thread thread2 = new Thread(withdraw);
thread1.setName("小米");
thread2.setName("小牛");
thread1.start();
thread2.start();
}
}
//多个线程共享进程,所以使用实现Runnable方式
class Withdraw implements Runnable {
//共享10000元
static int money = 10000;
static boolean loop = true;
@Override
public void run() {
//通过loop来控制循环
while (loop) {
//获取锁
draw();
}
}
//1.这里使用synchronized 实现线程同步
//2.多个线程执行到这里,就会去争夺this对象锁
//3.哪个线程争夺到this对象的锁,就执行业务
//4.争夺不到的,处于blocked状态,准备继续争夺
public /*方法一:synchronized */ void draw() {
//方法二:同步代码块,格式:synchronized(对象){业务}
//this对象是非公平锁,
synchronized (this){
if (money < 1000) {
System.out.println("钱取完了");
loop = false;
return;
}
try {
//休眠,0.1秒
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
money -= 1000;
//执行完这一句,会短暂的释放锁,继续下一轮锁的争夺
System.out.println(Thread.currentThread().getName() + "取出1000元,剩余:" + money);
}
}
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)