java多线程的(一)-之java线程的使用
一、摘要
每天都和电脑打交道,也相信大家使用过资源管理器杀掉过进程。而windows本身就是多进程的操作系统
在这里我们理解两组基本概念:
1、进程和线程的区别????
2、并行与并发的区别????
那么针对进程与线程而言:
什么是进程:进程其实就是一个运行的程序,操作系统会为这个进行资源分配从而执行程序
什么是线程:线程是程序的一个执行线索,即是进程的一个执行流程,一个进程内部可以开辟多个线程
对并行与并发而言:
什么是并行:并行指的是多个cpu同时去处理一段逻辑
什么是并发:并发指的个线程在抢夺cpu时间片,谁先抢到谁就执行,从而更加高效的利用资源
二:多线程创建的三种方式
1、继承Thread类
2、实现Runnable接口
3、通过线程池进行线程的创建,后续章节会讲到
三、线程创建方式一:继承Thread类
这种方式创建线程缺点如下:
1、每次都创建新的线程对象具有各自的变量,无法共享数据
2、java只支持单继承,碰到线程类有一个父类的时候,则无法继承Thread类
public class Demo1 {
public static void main(String[] args) {
MyThread myThread=new MyThread();
myThread.start();
System.out.println("继承Thread类");
}
}
class MyThread extends Thread
{
public void run()
{
System.out.println("创建的线程");
}
}
四、线程创建方式二:实现Runnable接口
使用该方式创建线程时:
1、可以实现成员变量的共享
2、可以实现多接口,不存在继承问题
public class MyRunnable implements Runnable {
@Override
public void run() {
System.out.println("运行中!");
}
}
public class Demo2{
public static void main(String[] args) {
Runnable runnable=new MyRunnable();
Thread thread=new Thread(runnable);
thread.start();
System.out.println("运行结束!");
}
}
五、多线程并发安全问题
1、所谓多线程并发安全指的是多个线程在去并发操作共享的资源时,操作过程中包含多个步骤,由于线程的并发则会造成执行混乱的一些问题
2、解决办法一:使用同步代码块隔离多线程
/**
* Created by BeiChen on 2018/3/18.
*/
public class ThreadDemo1 {
public static void main(String[] args) {
MyThread mt=new MyThread();
Thread t1=new Thread(mt);
Thread t2=new Thread(mt);
t1.start();
t2.start();
}
} class MyThread implements Runnable{
int num=100;
@Override
public void run() {
while (true){
synchronized (this){
if(num>0){
System.out.println(Thread.currentThread().getName()+"执行了,此时num值为"+num);
}else{
break;
}
num--;
}
}
}
}
从上述代码中我们可以得出:
1)、同步代码块要将造成多线程并发安全问题的代码都要括上,一般来说多线程并发安全问题都是由于同时读取和修改共同执行造成的问题,在使用同步代码块时,将读和改的操作都要括起来。
2)、同步代码块可以解决多线程并发安全问题,但是在同步代码块中相当于将多线程变成了单线程,程序的性能会降低,所以同步代码块中的代码不能太多,应该在保证能够防止多线程并发安全问题的前提下代码尽量少,从而减少程序代码对性能的影响
3)、任何对象都可以当做锁对象来使用,但是必须保证这个对象是所有要用这个锁的并发线程都能看到的同一个对象才可以。多个线程用同一个锁对象,在它身上控制锁的开光,控制程序的并发
常见的锁对象:共享资源对象,this ,类的class字节码对象
3、解决办法二:使用同步函数来解决
上述代码也可以改写成:
public class ThreadDemo1 {
public static void main(String[] args) {
MyThread mt=new MyThread();
Thread t1=new Thread(mt);
Thread t2=new Thread(mt);
t1.start();
t2.start();
}
}
class MyThread implements Runnable{
int num=0;
@Override
public void run() {
for(int i=0;i<100;i++){
add(i);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public synchronized void add(int i) {
System.out.println(Thread.currentThread().getName() + "执行了,此时i值为" + i);
}
}
在上述使用同步函数处理并发安全问题时,我们可以看出同步可以将这个方法设置为同步方法,这个方法本身自动就会用锁隔离
同时同步函数默认使用的锁对象是this
如果同步函数是静态方法,没有this对象,此时使用的锁对象是当前的额字节码对象
六、死锁问题
死锁问题指的是两个线程资源在互相的等待导致了死锁,死锁问题一旦产生就是很严重的问题
代码案例如下:
/**
* Created by BeiChen on 2018/3/18.
*/
public class DeadLockDemo {
public static void main(String[] args) {
new Thread(new Lock1()).start();
new Thread(new Lock2()).start();
}
}
class Demo1{}
class Demo2{}
class Lock1 implements Runnable{ @Override
public void run() {
System.out.println("lock1 开始运行");
synchronized (Demo1.class){
System.out.println("Lock1 锁住了 Demo1");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (Demo2.class){
System.out.println("Lock1 锁住了Demo2");
}
}
}
}
class Lock2 implements Runnable{ @Override
public void run() {
System.out.println("lock2 开始运行");
synchronized (Demo2.class){
System.out.println("Lock2 锁住了 Demo2");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (Demo1.class){
System.out.println("Lock2 锁住了Demo1");
}
}
}
}
在上述我们可以看出Lock1和Lock2相互锁住了自己的对象导致死锁的问题产生
最简单的解决办法如下:
将同步嵌套的代码放开,不要进行同步嵌套,同步嵌套是造成死锁的必然原因,想要防止死锁,只要保证没有同步嵌套就可以了
代码改造如下:
/**
* Created by BeiChen on 2018/3/18.
*/
public class DeadLockDemo {
public static void main(String[] args) {
new Thread(new Lock1()).start();
new Thread(new Lock2()).start();
}
}
class Demo1{}
class Demo2{}
class Lock1 implements Runnable{ @Override
public void run() {
System.out.println("lock1 开始运行");
synchronized (Demo1.class) {
System.out.println("Lock1 锁住了 Demo1");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
synchronized (Demo2.class){
System.out.println("Lock1 锁住了Demo2");
} }
}
class Lock2 implements Runnable{ @Override
public void run() {
System.out.println("lock2 开始运行");
synchronized (Demo2.class) {
System.out.println("Lock2 锁住了 Demo2");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
synchronized (Demo1.class){
System.out.println("Lock2 锁住了Demo1");
}
}
}
java多线程的(一)-之java线程的使用的更多相关文章
- Java多线程基础:进程和线程之由来
转载: Java多线程基础:进程和线程之由来 在前面,已经介绍了Java的基础知识,现在我们来讨论一点稍微难一点的问题:Java并发编程.当然,Java并发编程涉及到很多方面的内容,不是一朝一夕就能够 ...
- Java多线程之~~~使用Exchanger在线程之间交换数据[这个结合多线程并行会有解决很多问题]生产者消费者模型
http://blog.csdn.net/a352193394/article/details/39503857 Java多线程之~~~使用Exchanger在线程之间交换数据[这个结合多线程并行会 ...
- Java多线程学习(八)线程池与Executor 框架
目录 历史优质文章推荐: 目录: 一 使用线程池的好处 二 Executor 框架 2.1 简介 2.2 Executor 框架结构(主要由三大部分组成) 2.3 Executor 框架的使用示意图 ...
- Java多线程-两种常用的线程计数器CountDownLatch和循环屏障CyclicBarrier
Java多线程编程-(1)-线程安全和锁Synchronized概念 Java多线程编程-(2)-可重入锁以及Synchronized的其他基本特性 Java多线程编程-(3)-从一个错误的双重校验锁 ...
- “全栈2019”Java多线程第十三章:线程组ThreadGroup详解
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...
- “全栈2019”Java多线程第十一章:线程优先级详解
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...
- “全栈2019”Java多线程第九章:判断线程是否存活isAlive()详解
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...
- “全栈2019”Java多线程第五章:线程睡眠sleep()方法详解
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...
- 1、Java多线程基础:进程和线程之由来
Java多线程基础:进程和线程之由来 在前面,已经介绍了Java的基础知识,现在我们来讨论一点稍微难一点的问题:Java并发编程.当然,Java并发编程涉及到很多方面的内容,不是一朝一夕就能够融会贯通 ...
- Java 多线程基础(四)线程安全
Java 多线程基础(四)线程安全 在多线程环境下,如果有多个线程在同时运行,而这些线程可能会同时运行这段代码.程序每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的,就是线 ...
随机推荐
- monkey日志分析
Monkey测试的og分析,我们可以通过几个关键词来判断测试是否通过.1)Monkey finished打开LOG,查看log的最下端,是否有类似以下字段:## Network stats: elap ...
- Shell 的特殊变量
2017-08-02 1.$0 获取当前脚本的名称或全路径 cat name.sh Linux shell sh name.sh echo $0 name.sh 2.$n(n >=1) 获取脚本 ...
- 吐血整理:人工智能PDF中文教材资源包2.73G基本包含全部学习资料-人工智能学习书单
吐血整理:人工智能PDF中文教材资源包2.73G基本包含全部学习资料 人工智能学习书单(关注微信公众号:aibbtcom获取更多资源) 文末附百度网盘下载地址 人工神经网络与盲信号处理 人工神经网络与 ...
- webpack3配置字体图标和打包相关问题
webpak配置字体图标有两种方式 一.将字体图标和css打包到同一个文件中. 1.首先需要安装url-loader npm install --save-dev url-loader 2.相关配置如 ...
- ssm+maven多模块项目整合
我的项目一共会分为4个模块:entity.dao.service和web 一.创建父模块 填写GroupId与ArtifactId 填写项目名称和项目保存路径 因为是父模块所以src包可以删除 二.创 ...
- 【Luogu3807】【模板】卢卡斯定理(数论)
题目描述 给定\(n,m,p(1≤n,m,p≤10^5)\) 求 \(C_{n+m}^m mod p\) 保证\(P\)为\(prime\) \(C\)表示组合数. 一个测试点内包含多组数据. 输入输 ...
- 【BZOJ1975】【SDOI2010】魔法猪学院(搜索,A*,贪心)
我已经沉迷于粘贴题目地址了... 题解 很显然的贪心呀, 就是一定是最短的若干条路径的长度 所以,不断拓展k短路就可以了 至于怎么用A* 评估函数f(x)=dis[x]+g[x] 其中,dis是到N号 ...
- 【SDOI2009】HH的项链 (莫队)
题面 Description HH有一串由各种漂亮的贝壳组成的项链.HH相信不同的贝壳会带来好运,所以每次散步 完后,他都会随意取出一段贝壳,思考它们所表达的含义.HH不断地收集新的贝壳,因此, 他的 ...
- [HDU5765]Bonds
题面 题意 给出一张\(n\)点\(m\)边无向连通图,求每条边出现在多少个割集中. \(n\le20,m\le\frac{n(n-1)}{2}\) sol 所谓割集,就是指把\(n\)个点分成两个集 ...
- javascript 推箱子游戏介绍及问题
最近没什么事情,我的一个亲戚在学校学习PHP,课程中老师让他们编写一个javascript版本的推箱子小游戏,他没什么头绪,就来问我,我当时很闲,就随口答应他包在我身上.结果真正写的时候还是花了点时间 ...