JAVA开发知识之Java的线程
Java多线程讲解
一丶多线程简介
1.进程的概念
进程是什么,进程就是一个程序在运行中的一个实例.比如QQ.比如浏览器.这个就是多进程的状态.
意思就是可以同时运行多个程序.
可以打开任务管理器.观看我们的进程 ctrl + shift + esc 或者 ctrl + alt +del
2.线程概念
线程,线程就是同一个进程的多条路.我们知道代码都是顺序执行的.多线程的意思就是可以有多条代码一同执行.它是归属于进程的.进程可以看做一个外壳.真正执行代码的是线程.进程唯一的个线程就是执行代码.如果没有线程,那么进程也终结了.
Java中的单线程代码:
public static void main(String[] args) throws Exception {
for (int i = 0; i < 100;i++) {
System.out.println("i = " + i);
Thread.sleep(1000);
}
for (int j = 0; j < 100;j++) {
System.out.println("j = " + j);
Thread.sleep(1000);
}
}
上面就是典型的单线程执行代码.第一个循环不执行完毕,第二个循环是不会执行的.
多线程程序则是,我可能当前执行打印i 后面就可能执行打印j了.
3.Java中多线程Thread类
java.lang.Thread是个线程类.核心的类.
还有一个借口是 Runnable 也可以实现多线程.
Thread类中需要了解的方法.
public void start()使该线程开始执行;指定run方法
public void run();我们需要重写这个方法.调用start则会执行我们的线程.
public static void sleep(long millis,int nanos)throws InterruptedException 延时命令给一个时间
二丶多线程的创建
线程的创建有两种办法,第一种继承Thread类.重写run方法.调用start开始执行.
第二种实现Runnable接口
1.继承Thread类.重写run方法.
public class ExtenThreadTest extends Thread {
public void run() {
for(int i = 0; i < 10; i ++) {
System.out.println("i = " + i);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
}
}
}
外部调用:
public static void main(String[] args) throws Exception {
ExtenThreadTest t = new ExtenThreadTest();
t.start();
for(int j = 0; j < 100; j++) {
System.out.println("j = " + j);
Thread.sleep(100);
}
}
此时我们的run方法打印我们的i值, 主方法打印我们的j值.当线程发生切换的时候就会显示一种打印完i之后打印j的效果.
2.实现Runalbe接口.
有时候我们的java继承了一个类.但是自己当前类还需要可以支持多线程.现在不能继承Thread类了.
因为Java不能多继承.所以Java为我们提供了一个接口,实现这个接口即可. Runnable();
如果观看源代码可以得知,Thread类其实也是实现了Runnable接口.并且对Runnable接口的run方法重写的.
步骤:
- 1.创建一个类,实现Runnable接口,并且重写里面的run方法.
- 2.使用Thread创建Thread对象.构造方法.填写我们类的实例.
- 3.因为填写的是我们的实例.所以相当于重写了run方法.构成了多态
- 4.调用start()函数启动线程.
具体代码例子;
public class ExtenThreadTest implements Runnable {
public void run() {
for(int i = 0; i < 10; i ++) {
System.out.println("i = " + i);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
}
}
}
使用代码
public static void main(String[] args) throws Exception {
Thread t = new Thread(new ExtenThreadTest()); //这里不同
t.start();//启动线程
t.setName("ExtenThreadTest");
for(int j = 0; j < 100; j++) {
System.out.println("j = " + j);
Thread.sleep(100);
}
}
三丶线程的启动和终止
1.线程的启动使用start()方法启动.如果直接调用run就是单线程程序
2.线程的结束可以使用stop();不过这个方法已经废弃了.正常的是你的线程中给一个标记. 通过外部设置标记.来让线程自然停止.
3.使用interrupt();方法.这个方法可能会抛异常,不推荐.
四丶线程的状态
线程的状态分为以下状态:
1.NEW 新建状态 当一个线程实例化之后,就处于这个状态
2.RUNNABLE 可以运行的, 当使用start方法的时候就是这个.线程可以用,但是不一定你能用.
3.BLOCKED 阻塞状态,使用Sleep()的时候是这个
4.WAITING 等待状态,两个线程进行通信的时候,进行登台
5.TIMED_WAITING 等待时间过了,就是Timed_waiting状态
6.TERMINATED 线程的正常终止.
五丶线程控制的基本方法
1.线程名称
每个线程都用自己的名字,我们可以在构造的时候传入线程名字
使用线程的 getName()获取名称.
Thread.currentThread().getNmae(); 获得当前线程名字. 主要方法就是 getNmae().
setName(String name);给线程设置名字
2.线程优先级
线程的优先级默认就是0,我们可以设置.
Thread t = new Thread();
t.setPriority(Thread.MAX_PRIORITY);
t.SETpRIORITY(Thread.MIN_PRIORITY); 一般不设置,主要是CPU操作的获取时间片
3.Sleep()方法
Sleep(); 方法就是让当前线程等待一下.将时间片放出去,cpu就会去指向其它线程.
使用Sleep之后,线程就是阻塞状态, blocked, 睡眠完毕之后就是 runable状态.
使用Sleep();会出现一个异常.代表你给我终止了.
如下代码:
public void fun()
{
for(int i = 0; i < 10;i++)
{
try
{
Thread.sleep(1000);
}
catch(InterruptedException e){
e.printstackTrace();
}
if (i >=5){
this.interrupt(); 这句代码会产生异常
}
}
}
4.join()方法
join合并线程
join什么意思?
比如两个线程,有main线程,跟自己的线程.
我们不是用join之前,两个线程是乱序执行,就是线程切换着执行,如果使用 join方法.
那么两个线程就合并了,就会变成顺序执行.
5.isAlive()方法
判断当前是否还活着
isAlive();判断当前线程状态.
六丶线程的同步
什么是同步?
我们可以想一下, 有100个苹果, 有n个学生,来一个学生,我们发一个苹果.最后直到将100个苹果发完为止.
但是在程序中不是这样的,线程操作的时候,就会产生同步问题,同步问题就是指,这个线程在出售苹果的时候,另一个线程也在出售苹果.但是这个线程出售苹果之后还没有记录.另一个线程就已经卖出去了.这就导致了.卖出的苹果 大于实际记录的苹果,就出现了问题了. 怎么解决.解决方法就是这个线程卖的时候,另一个线程等待.当卖出去,并记录完毕你才可以去卖,你在卖的过程中,别人不能卖.
同步问题就是产生在没有对一个共同操作的变量进行保护,才会出现这个问题.在汇编的角度来说就是CPU切换了,而汇编代码还没有执行.就出现问题了.等切换回来再去操作就已经不对了.
1.多个线程共享一个资源需要进行保护,否则出现同步问题.
2.同步: 多线程中的代码,同一时间只能有一个代码访问是同步
3.异步: 多线程就是异步的.
锁机制实现同步, (lock unlock 英文);
4.以某一个对象实现枷锁跟解锁,关键字
synchronized(对象){
你的同步代码
}
对象可以使this
使用锁的时候注意的问题
- 1.注意是否是共享资源
代码例子如下:
Thread w1 = new Thread(new MyThread(),"w1"); MyThread是自己的类,继承了Thread,并且有自己的成员变量,num
Thread w2 = new Thread(new MyThread(),"w2");
w1.start();
w2.start();
这样是错误的,如果在创建Thread的实例,构造方法传入的使我们的MyThread,那么资源就不是共享的了.
七丶死锁
什么是死锁,死锁我们可以简单了解为, 一个人上厕所的过程,另一个人不能上.但是到最后可能出现一个问题.另一人一直等,而再则所里面的人也出不来. 这样的话就成死锁了.
死锁一般就是同步中. 一个对象还没打开,另一个对象在等待访问.就会造成死锁问题.
八丶线程的通信
两个线程访问同一个资源的时候,必须产生通信才可以,一个线程要等待.另一个线程去操作.
wait() 与notify()等待 通知 方法.
JAVA开发知识之Java的线程的更多相关文章
- Java开发知识之Java的异常处理
Java开发知识之Java的异常处理 一丶异常概述 在讲解异常之前,我们要搞清楚.什么是异常. 通俗理解就是我们编写的程序出问题了.进行处理的一种手段. 比如我们的QQ.有的时候就崩溃了.比如出现xx ...
- Java开发知识之Java中的Map结构
Java开发知识之Java中的Map结构 一丶Map接口 Map没有实现Collection接口,提供的是Key 到Value的映射. Map中.不能包含相同的Key,每个Key只能映射一个Value ...
- Java开发知识之Java中的集合Set接口以及子类应用
---恢复内容开始--- Java开发知识之Java中的集合Set接口以及子类应用 一丶Set接口以及作用 在上一讲.我们熟悉了接口的实现图.以及自己各有的子类. List接口主要存储的数据是可以重复 ...
- Java开发知识之Java中的集合上List接口以及子类讲解.
Java开发知识之Java中的集合类 一丶什么是集合类 如果你学习说数据结构,那么学习集合就很简单. 因为集合就是存储数据的结构. 例如 有链表结构 (list ) 还有 map结构.等等. 集合类就 ...
- Java开发知识之Java中的泛型
Java开发知识之Java中的泛型 一丶简介什么是泛型. 泛型就是指泛指任何数据类型. 就是把数据类型用泛型替代了. 这样是可以的. 二丶Java中的泛型 Java中,所有类的父类都是Object类. ...
- Java开发知识之Java的枚举
Java开发知识之Java的枚举 一丶什么是枚举 枚举可以理解为就是常量,在Java中我们定义常量.都是用 final语句. C++中都是用const关键字. 枚举跟C++概念都是一样的.就是特定的常 ...
- Java开发知识之Java类的高级特性,内部类.以及包使用.跟常量关键字
Java开发知识之Java类的高级特性,内部类.以及包使用.跟常量关键字 一丶Java中包的机制 首先包其实就是个文件夹.作用就是管理类. Java中每次定义一个类的时候.通过Java编译之后.都会生 ...
- Java开发知识之Java的继承多态跟接口*
Java开发知识之Java的继承多态跟接口 一丶继承 1.继承的写法 在Java中继承的 关键字是 extends 代表一个类继承另一个类. 继承的含义以及作用: 继承就是基于某个父类的扩展.制定出来 ...
- Java开发知识之Java的数字处理类Math类
Java开发知识之Java的数字处理类Math类 一丶Java.text.DecimalFormat类与NumberFormat类 首先 Java.text.DecimalFormat指的是Decim ...
- Java开发知识之Java的包装类
Java开发知识之Java的包装类 一丶什么是包装类 包装类的意思就是对基本数据类型封装成一个类.这些类都是Number的子类.区别就是封装数据类型不同.包含的方法基本相同. 具体可以查询JAVA A ...
随机推荐
- Javascript 标识符及同名标识符的优先级
一.定义 标识符(Identifier)就是一个名字,用来对变量.函数.属性.参数进行命名,或者用做某些循环语句中的跳转位置的标记. //变量 var Identifier = 123; //属性 ( ...
- pytroch nn.Module源码解析(1)
今天在写一个分类网络时,要使用nn.Sequential中的一个模块,因为nn.Sequential中模块都没有名字,我一时竟无从下笔.于是决定写这篇博客梳理pytorch的nn.Module类,看完 ...
- 新建一个express项目的流程
1.先创建一个文件夹,然后创建一个项目,默认有一个:package.json 文件 #初始化项目 npm init 2.初始化项目会出现一个默认的提醒 #这个实用程序将指导您创建一个包,json文件. ...
- JavaScript经典作用域问题(转载)
题目 var a = 10; function test(){ a = 100; console.log(a); console.log(this.a); var a; console.log(a); ...
- Notepad++常用快捷键
Ctrl-H 打开Find / Replace 对话框 Ctrl-D 复制当前行 Ctrl-L 删除当前行 Ctrl-T 上下行交换 F3 找下一个 Shift-F3 ...
- linux-Vim命令合集
Vim命令合集 命令历史 以:和/开头的命令都有历史纪录,可以首先键入:或/然后按上下箭头来选择某个历史命令. 启动vim 在命令行窗口中输入以下命令即可 vim 直接启动vim vim filena ...
- 下载 mysql 数据库 的步骤 完整版
1. 官网(点这里)上下载 2. 3. 4. 5. 6. 7.
- unittest中常用的几个断言
a.相等 (a==b)内容一样,类型一致 from init import * import unittest class Baidu_Title(Info): def test_baidu_titl ...
- Tomcat 集群中 实现session 共享的三种方法
前两种均需要使用 memcached 或 redis 存储 session ,最后一种使用 terracotta 服务器共享. 建议使用 redis ,不仅仅因为它可以将缓存的内容持久化,还因为它支持 ...
- [Swift]LeetCode454. 四数相加 II | 4Sum II
Given four lists A, B, C, D of integer values, compute how many tuples (i, j, k, l)there are such th ...