Java多线程解决多线程安全问题

简介: 1.理解多线程原理2.掌握多线程的实现方法3.掌握多线程的控制方法4.能够通过多线程解决实际问题。

1、线程安全

线程安全的三种解决方法:同步代码块,同步方法和lock锁。

线程安全是多线程编程时的计算机程序代码中的一个概念。在拥有共享数据的多条线程并行执行的程序中,线程安全的代码会通过同步机制保证各个线程都可以正常且正确的执行,不会出现数据污染等意外情况。

1、同步代码块

详细代码:

publicclass同步代码块 {
publicstaticvoidmain(String[] args) {
TicketWindow1task=newTicketWindow1();
newThread(task,"窗口一").start();
newThread(task,"窗口二").start();
newThread(task,"窗口三").start();
    }
}
classTicketWindow1implementsRunnable{
privateinttickets=10;
Objectlock=newObject();
publicvoidrun() {
while(true){
synchronized (lock) {
try {
Thread.sleep(10);
                } catch (InterruptedExceptione) {
// TODO Auto-generated catch blocke.printStackTrace();
                }
if(tickets>0){
System.out.println(Thread.currentThread().getName()+"--卖出的票"+tickets--);
            }
        }
    }
  }
}

image.png

2、同步方法

详细代码:

publicclass同步方法 {
publicstaticvoidmain(String[] args) {
TicketWindow2task=newTicketWindow2();
newThread(task,"窗口一").start();
newThread(task,"窗口二").start();
newThread(task,"窗口三").start();
    }
}
classTicketWindow2implementsRunnable{
privateinttickets=10;
@Overridepublicvoidrun() {
// TODO Auto-generated method stubwhile(true){
SendTask();
        }
    }
privatesynchronizedvoidSendTask() {
// TODO Auto-generated method stubtry {
Thread.sleep(10);
        } catch (InterruptedExceptione) {
// TODO Auto-generated catch blocke.printStackTrace();
        }
if(tickets>0){
System.out.println(Thread.currentThread().getName()+"--卖出的票"+tickets--);
        }else{
System.exit(0);
        }
    }
}

image.png

3、lock锁


详细代码:

importjava.util.concurrent.locks.Lock;
importjava.util.concurrent.locks.ReentrantLock;
publicclasslock锁 {
publicstaticvoidmain(String[] args) {
TicketWindow3task=newTicketWindow3();
newThread(task,"窗口一").start();
newThread(task,"窗口二").start();
newThread(task,"窗口三").start();
    }
}
classTicketWindow3implementsRunnable{
privateinttickets=10;
Lockl=newReentrantLock();
publicvoidrun() {
while(true){
l.lock();
try {
Thread.sleep(10);
                } catch (InterruptedExceptione) {
// TODO Auto-generated catch blocke.printStackTrace();
                }
if(tickets>0){
System.out.println(Thread.currentThread().getName()+"--卖出的票"+tickets--);
            }
l.unlock();
        }
    }
}

image.png


2、死锁

死锁是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程。

publicclass线程死锁implementsRunnable {
staticObjectchopsticks=newObject();
staticObjectknifeAndFork=newObject();
privatebooleanflag;
线程死锁(booleanflag){
this.flag=flag;
    }
@Overridepublicvoidrun() {
// TODO Auto-generated method stubif(flag){
while(true){
synchronized (chopsticks) {
System.out.println(Thread.currentThread().getName()+"---if---chopsticks");
synchronized (knifeAndFork) {
System.out.println(Thread.currentThread().getName()+"---if---knifeAndFork");
                    }
                }
            }
        }else{
while(true){
synchronized (knifeAndFork) {
System.out.println(Thread.currentThread().getName()+"---else---knifeAndFork");
synchronized (chopsticks) {
System.out.println(Thread.currentThread().getName()+"---else---chopsticks");
            }
        }
    }
  }
 }
}
publicclassExample {
publicstaticvoidmain(String[] args) {
线程死锁d1=new线程死锁(true);
线程死锁d2=new线程死锁(false);
newThread(d1,"Chinese").start();
newThread(d2,"American").start();
    }
}

image.png

3、线程通信

ITC,是Inter-Thread Communication的缩写,意思是线程间通信。

publicclassMyThread {
publicstaticObjectobject=newObject();
publicstaticvoidmain(String[] args) {
Thread1t1=newThread1();
Thread2t2=newThread2();
t1.start();
t2.start();
    }
staticclassThread1extendsThread{
publicvoidrun() {
synchronized (object) {
System.out.println("线程"+Thread.currentThread().getName()+"获取到了锁");
try{
System.out.println("线程"+Thread.currentThread().getName()+"阻塞并释放锁。。。");
object.wait();
            }catch(InterruptedExceptione){
            }
System.out.println("线程"+Thread.currentThread().getName()+"执行完成。。。。。。");
    }
}
staticclassThread2extendsThread{
publicvoidrun() {
synchronized (object) {
System.out.println("线程"+Thread.currentThread().getName()+"获取到了锁");
object.notify();
System.out.println("线程"+Thread.currentThread().getName()+"唤醒了正在wait的线程");
        }
System.out.println("线程"+Thread.currentThread().getName()+"执行完成。。。。。。");
       }
       }
    }
}

image.png

相关文章
|
1天前
|
安全 Java
java 中 i++ 到底是否线程安全?
本文通过实例探讨了 `i++` 在多线程环境下的线程安全性问题。首先,使用 100 个线程分别执行 10000 次 `i++` 操作,发现最终结果小于预期的 1000000,证明 `i++` 是线程不安全的。接着,介绍了两种解决方法:使用 `synchronized` 关键字加锁和使用 `AtomicInteger` 类。其中,`AtomicInteger` 通过 `CAS` 操作实现了高效的线程安全。最后,通过分析字节码和源码,解释了 `i++` 为何线程不安全以及 `AtomicInteger` 如何保证线程安全。
java 中 i++ 到底是否线程安全?
|
1天前
|
缓存 Java 调度
Java中的多线程编程:从基础到实践
【10月更文挑战第24天】 本文旨在为读者提供一个关于Java多线程编程的全面指南。我们将从多线程的基本概念开始,逐步深入到Java中实现多线程的方法,包括继承Thread类、实现Runnable接口以及使用Executor框架。此外,我们还将探讨多线程编程中的常见问题和最佳实践,帮助读者在实际项目中更好地应用多线程技术。
8 3
|
1天前
|
缓存 安全 Java
Java中的多线程编程:从基础到实践
【10月更文挑战第24天】 本文将深入探讨Java中的多线程编程,包括其基本原理、实现方式以及常见问题。我们将从简单的线程创建开始,逐步深入了解线程的生命周期、同步机制、并发工具类等高级主题。通过实际案例和代码示例,帮助读者掌握多线程编程的核心概念和技术,提高程序的性能和可靠性。
7 2
|
2天前
|
Java
Java中的多线程编程:从基础到实践
本文深入探讨Java多线程编程,首先介绍多线程的基本概念和重要性,接着详细讲解如何在Java中创建和管理线程,最后通过实例演示多线程的实际应用。文章旨在帮助读者理解多线程的核心原理,掌握基本的多线程操作,并能够在实际项目中灵活运用多线程技术。
|
2天前
|
Java 开发者
Java中的多线程基础与应用
【10月更文挑战第24天】在Java的世界中,多线程是提高效率和实现并发处理的关键。本文将深入浅出地介绍如何在Java中创建和管理多线程,以及如何通过同步机制确保数据的安全性。我们将一起探索线程生命周期的奥秘,并通过实例学习如何优化多线程的性能。无论你是初学者还是有一定经验的开发者,这篇文章都将为你打开一扇通往高效编程的大门。
7 0
|
21天前
|
存储 消息中间件 资源调度
C++ 多线程之初识多线程
这篇文章介绍了C++多线程的基本概念,包括进程和线程的定义、并发的实现方式,以及如何在C++中创建和管理线程,包括使用`std::thread`库、线程的join和detach方法,并通过示例代码展示了如何创建和使用多线程。
36 1
C++ 多线程之初识多线程
|
6天前
|
Java 开发者
在Java多线程编程中,创建线程的方法有两种:继承Thread类和实现Runnable接口
【10月更文挑战第20天】在Java多线程编程中,创建线程的方法有两种:继承Thread类和实现Runnable接口。本文揭示了这两种方式的微妙差异和潜在陷阱,帮助你更好地理解和选择适合项目需求的线程创建方式。
11 3
|
6天前
|
Java 开发者
在Java多线程编程中,选择合适的线程创建方法至关重要
【10月更文挑战第20天】在Java多线程编程中,选择合适的线程创建方法至关重要。本文通过案例分析,探讨了继承Thread类和实现Runnable接口两种方法的优缺点及适用场景,帮助开发者做出明智的选择。
9 2
|
6天前
|
Java
Java中多线程编程的基本概念和创建线程的两种主要方式:继承Thread类和实现Runnable接口
【10月更文挑战第20天】《JAVA多线程深度解析:线程的创建之路》介绍了Java中多线程编程的基本概念和创建线程的两种主要方式:继承Thread类和实现Runnable接口。文章详细讲解了每种方式的实现方法、优缺点及适用场景,帮助读者更好地理解和掌握多线程编程技术,为复杂任务的高效处理奠定基础。
15 2
|
6天前
|
Java 开发者
Java多线程初学者指南:介绍通过继承Thread类与实现Runnable接口两种方式创建线程的方法及其优缺点
【10月更文挑战第20天】Java多线程初学者指南:介绍通过继承Thread类与实现Runnable接口两种方式创建线程的方法及其优缺点,重点解析为何实现Runnable接口更具灵活性、资源共享及易于管理的优势。
16 1