第37节:多线程安全问题
定义用户去银行存钱,每次存100,存3次
class Bank {
// 总数
private int sum;
// 定义方法
public void add(int num){
// 传入参数
sum = sum + sum;
// 加后的值
System.out.println("sum"+sum);
}
}
class Demo implements Runnable{
// 定义银行类对象,创建实例对象
private Bank b = new Bank();
// 线程run()
public void run(){
for(int x=0; x<3; x++){
// 将参数放入对象方法中
b.add(100)
}
}
}
// 测试类
class Test{
public static void main(String[] args){h
// 创建对象
Demo d=new Demo();
// 创建线程对象
Thread t1 = new Thread(d);
Thread t2 = new Thread(d);
// 线程开启
t1.start();
t2.start();
}
}
如果出现这个代码,出现了多线程安全问题。共性数据即共享对象中的数据。
class Bank {
// 总数
private int sum;
// 创建对象
private Object obj = new Object();
// 定义方法
public void add(int num){
synchronized(obj){
// 传入参数
sum = sum + sum;
// 加后的值
System.out.println("sum"+sum);
}
}
}
安全问题,加了同步可以解决数据安全。
class Tickets implements Runnable{
private int tickets = 100;
private Object obj = new Object();
public void run(){
whilt(true){
synchronized(obj){
if(tickets>0){
try{
Thread.sleep(1000);
}catch(Exception e){
System.out.println(Thread.currentThread().getName()+tickets);
}
}
}
}
}
}
饿汉式
class Single{
private static final Single s = new Single();
private Single(){)
public static Single getInstance(){
return s;
}
}
懒汉式
class Single{
private static Single s = null;
private Single(){}
public static Single getInstance(){
if(s==null){
s = new Single();
}
return s;
}
}
多线程
在同一时间,做多件事情.
创建线程的方法
继承类Thread并重写run(),run()称为线程体;用这种方法定义的类不能再继承其他类。
class FirstThread extends Thread{
public void run(){
for(int i=0;i<100;i++){
System.out.println("FirstThread"+i);
}
}
}
class Test{
public static void main(Sting args[]){
FirstThread ft = new FirstThread();
ft.start();
for(int i = 0; i<100;i++){
System.out.println("main"+i):
}
}
}
接口Runnable的类作为线程的目标对象
class Test implements Runnable{
public void run(){
for(int i = 0;i<100;i++){
System.out.println("Runnable"+i);
}
}
}
class Test{
public static void main(String args[]){
Test test = new Test();
Thread t = new Thread(test);
System.out.println(t.getPriority());
t.start();
}
}
唤醒线程
线程类
image.png
主方法类
image.png
线程同步与等待
image.png线程的同步
关键字synchronized
多线程就是调用这个synchronized的方法的,
当线程用了这个方法,那么其他线程想使用这个方法时就得等,直到线程使用完该调用的方法。
同步中的等待
wait()方法:暂时让出cpu;
notifyAll()方法:等待结束。
线程是程序中的执行线程,在Java虚拟机中允许应用程序并发地运行多个执行线程,每个线程独有它自己的一个优先级,高的优先级的执行线程优先于低优先级的线程,每个线程都可以有或者不可以标记的一个守护程序。当一个线程中的运行代码创建一个Thread对象的时候,该线程的初始化优先级就被设定,只有创建线程是守护线程的时候,这个线程才是守护程序。
在Java中的虚拟机启动,通常会有单个非守护线程,一般在代码中有个线程为主线程,main方法。
第36节:Java当中的线程
第35节:Java面向对象中的多线程
这两篇文章讲了什么是进程,什么是线程等一些概念。
进程要执行需要依赖线程,线程是进程中最小的执行单位,一个进程中至少要有一个线程,在线程中串行是单条线程来执行多个任务来说的,任务A到任务B到任务C,只有任务A完成了后才开始到任务B,一条线完成。并行为开启多个线程同时进行任务,同一时刻发生任务A,任务B,任务C。
什么是线程安全
线程出现问题是在多线程的情况之下产生的。出现线程安全问题,如何去解决这个问题呢?用synchronized关键字,用来控制线程同步的,可以让线程在多线程的情况下,不被多个线程同时执行,保证我们数据的安全性。
public synchronized void add(int i){
...
}
Lock的引入让锁有了可操作性,它是在Java1.6被引入进来的,Lock可以去手动获取锁和释放锁。
// ReentrantLock是Lock的子类
private Lock lock = new ReentrantLock();
private void methodThread(Thread thread){
// 获取锁对象
lock.lock();
try {
System.out.println(thread.getName() + "获得了锁");
}catch(Exception e){
e.printStackTrace();
} finally {
System.out.println(thread.getName() + "释放了锁");
// 释放锁对象
lock.unlock();
}
}
往后余生,努力学习
简书作者:达叔小生
90后帅气小伙,爱编程,爱运营,爱折腾。
简书博客: https://www.jianshu.com/u/c785ece603d1
结语
- 下面我将继续对其他知识 深入讲解 ,有兴趣可以继续关注
- 小礼物走一走 or 点赞