线程及线程安全解决方法
来源:互联网 发布:绝食瘦下来知乎 编辑:程序博客网 时间:2024/06/07 09:30
/*
/*
线程:
多线程的好处: 多线程解决了在一个进程中同时可以执行多个任务代码的问题。
自定义线程的创建方式:
方式一:继承Thread.
1. 自定义一个类继承Thread类。
2. 重写Thread的run方法,把自定义线程的任务代码定义在run方法上。
3. 创建Thread子类的对象,并且调用start方法启动一个线程。
方式二: 实现Runnable接口。
1. 自定义一个类实现Runnable接口。
2. 实现Runnable接口中的run方法,把自定义线程的任务代码定义在run方法上。
3. 创建Runable实现类 的对象。
4. 创建Thread对象,并且把Runnable实现类的对象作为参数传递。
5. 调用Thread对象的start方法开启线程。
线程安全 问题的解决方案:
线程安全问题出现 的根本原因:
1. 必须要存在两个或者两个以上的线程共享着一个资源。
2. 操作共享资源的代码必须有两句或者两句以上。
1. 同步代码块
synchronized(锁){
需要被同步的代码
}
2. 同步函数。
修饰符 synchronized 返回值类型 函数名(形参列表..){
}
注意:
1. 同步代码块的锁可以是任意的对象。 同步函数的锁是固定 的,非静态函数的锁对象是this对象。 静态函数的锁对象是class对象。
2. 锁对象必须是多线程共享的对象,否则锁不住。
3. 在同步代码块或者是同步函数中调用sleep方法是不会释放锁对象的,如果是调用了wait方法是会释放锁对象的。
*/
public class Demo1 extends Thread {
public Demo1(String name){
super(name);
}
@Override
public void run() {
for(int i = 0 ; i< 100 ; i++){
System.out.println(Thread.currentThread().getName()+":"+ i);
}
}
public static void main(String[] args) {
Demo1 d = new Demo1("狗娃");
d.start(); //开启线程。 线程一旦开启就会指定run方法中 的代码。
for(int i = 0 ; i< 100 ; i++){
System.out.println(Thread.currentThread().getName()+":"+ i);
}
}
}
需求: 模拟3个窗口同时在售50张 票 。
问题1 :为什么50张票被卖出了150次?
出现 的原因: 因为num是非静态的,非静态的成员变量数据是在每个对象中都会维护一份数据的,三个线程对象就会有三份。
解决方案:把num票数共享出来给三个线程对象a使用。使用static修饰。
问题2: 出现了线程安全问题 ?
线程 安全问题的解决方案:sun提供了线程同步机制让我们解决这类问题的。
java线程同步机制的方式:
方式一:同步代码块
同步代码块的格式:
synchronized(锁对象){
需要被同步的代码...
}
同步代码块要注意事项:
1. 任意的一个对象都可以做为锁对象。
2. 在同步代码块中调用了sleep方法并不是释放锁对象的。
3. 只有真正存在线程安全问题的时候才使用同步代码块,否则会降低效率的。
4. 多线程操作的锁 对象必须 是唯一共享 的。否则无效。
需求: 一个银行账户5000块,两夫妻一个拿着 存折,一个拿着卡,开始取钱比赛,每次只能取一千块,要求不准出现线程安全问题。
方式二:同步函数
出现线程安全问题的根本原因:
1. 存在两个或者两个以上 的线程对象,而且线程之间共享着一个资源。
2. 有多个语句操作了共享资源。
*/
class SaleTicket extends Thread{
static int num = 50;//票数 非静态的成员变量,非静态的成员变量数据是在每个对象中都会维护一份数据的。
static Object o = new Object();
public SaleTicket(String name) {
super(name);
}
@Override
public void run() {
while(true){
//同步代码块
synchronized ("锁") {
if(num>0){
System.out.println(Thread.currentThread().getName()+"售出了第"+num+"号票");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
num--;
}else{
System.out.println("售罄了..");
break;
}
}
}
}
}
public class Demo4 {
public static void main(String[] args) {
//创建三个线程对象,模拟三个窗口
SaleTicket thread1 = new SaleTicket("窗口1");
SaleTicket thread2 = new SaleTicket("窗口2");
SaleTicket thread3 = new SaleTicket("窗口3");
//开启线程售票
thread1.start();
thread2.start();
thread3.start();
}
}
*/
- 线程及线程安全解决方法
- Java线程安全问题及线程安全解决方法
- STL线程安全的解决方法
- STL线程安全的解决方法
- Servlet线程安全的解决方法
- Servlet线程安全的解决方法
- Servlet线程安全的解决方法
- Servlet线程安全的解决方法
- Servlet线程安全的解决方法
- 线程安全问题及解决方法
- 如何退出当前线程及线程安全
- 线程通信,线程安全及解决方式
- 线程安全及不可变性
- 线程安全及不可变性
- 线程安全及不可变性
- Servlet生命周期及线程安全
- 线程安全及不可变性
- 线程安全及不可变性
- 关于SEO关键词密度的误区(SEO优化核心盘点补充)
- C++学习笔记--类模板
- 集合相关
- [机器学习:李宏毅]6、Backpropagation
- Android屏幕适配--六大适配方法
- 线程及线程安全解决方法
- Mysql
- webrtc中的网络反馈与控制
- POJ1426-Find The Multiple
- 家族 SSL_1896 (并查集)
- java 23种设计模式详解
- ORA-01940:无法删除当前已连接的用户
- 爬取百度百科[scrapy启发]
- 滴滴开源基于 Vue.js 的移动端组件库 cube-ui