JAVA多线程笔记总结.

开发安卓的过程中,常常会用到java的一些知识,有时候回忆起却有点模糊,索性把它写成博客,这样可以让自己对知识有更深入的理解,另一方面,以后也可以方便查看


看威哥的视频总结:

首先从以下几个方面对线程进行分析:

1、进程与线程

首先要分清进程与线程的概念:

进程是一个具有一定独立功能的程序,一个实体,每一个进程都有它自己的地址空间。

线程实际上是在进程基础之上的进一步划分,一个进程启动之后,里面的若干程序又可以划分成若干个线程。

它是进程中的一个执行路径,共享一个内存空间,线程之间可以自由切换,并发执行,一个进程最少有一个

线程(单线程程序) 

线程实现的两种方式:

Java中如果要想实现多线程的操作,有两种实现方法:

(1)一种是继承Thread

(2)另外一种是实现Runnable接口 (常用)在安卓开发中,常常使用匿名内部类:new Thread(Runnable target).start或new Thread(){.run方法..}

package com.vince;


/**
 * 进程:一个具有独立内存空间的执行程序
 * 线程:线程是进程中的其中一条执行路径(多条就是多线程),每个进程最少有一个线程
 * 同一个进程中的多个线程共享同一个内存空间
 * 实现多线程的两种方式:
 * 1、继承Thread类
 * 2、实现Runnable接口(推荐)
 * @author vince
 *
 */
public class ThreadDemo {


public static void main(String[] args) {



//使用
//创建一个线程对象
MyThread t1 = new MyThread();
t1.setPriority(Thread.MAX_PRIORITY);//设置抢占CPU执行时间的优先级(注意,只是机率大而已)
t1.setDaemon(true);//把t1设置为守护线程
//
// t1.run();//直接调用不是启动线程,而是在本线程中执行方法
t1.start();//线程已准备就绪,等待CPU的调度


MyRunnable r = new MyRunnable();
Thread t2 = new Thread(r);
System.out.println("isAlive="+t2.isAlive());
t2.start();
System.out.println("isAlive="+t2.isAlive());

for (int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName()+"-"+i);
try {
Thread.sleep(500);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
if(i==6){
// try {
// t1.join();//等待t1线程执行完毕
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
Thread.yield();//让出当次CPU的执行时间
}
}
}

//继承Thread类实现线程
static class MyThread extends Thread{
@Override
public void run() {
//在此方法中编写线程要执行的工作
for (int i = 0; i < 10; i++) {
try {
//在指定的毫秒数内让当前正在执行的线程休眠(暂停执行),
//此操作受到系统计时器和调度程序精度和准确性的影响。该线程不丢失任何监视器的所属权。
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"-"+System.currentTimeMillis()+"-"+i);
}
}
}
//实现Runnable接口的方式实现线程
static class MyRunnable implements Runnable{
@Override
public void run() {
//在此方法中编写线程要执行的工作
for (int i = 0; i < 10; i++) {
try {
//在指定的毫秒数内让当前正在执行的线程休眠(暂停执行),
//此操作受到系统计时器和调度程序精度和准确性的影响。该线程不丢失任何监视器的所属权。
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"-"+System.currentTimeMillis()+"-"+i);
}
}
}


}


2、线程的操作方法

可以直接查阅相关资料文档,几个常用的sleep,join等等。。。

3.线程同步

因为有时候往往多个线程处理同一个资源时,就容易出错,因此才需要同步,同步有三个方法

1.同步代码块

2.同步方法

3.Lock

当编写 synchronized 块时,有几个简单的准则可以遵循,这些准则在避免死锁和性能危险的风险方面大有帮助:

3、同步准则

(1)使代码块保持简短。把不随线程变化的预处理和后处理移出synchronized 块。

(2)不要阻塞。如InputStream.read()

(3)在持有锁的时候,不要对其它对象调用方法。

具体事例如下: 

package com.vince;


import java.util.concurrent.locks.ReentrantLock;


/**
 * 线程同步 1、同步代码块 2、同步方法 3、Lock
 * 同步会牺牲性能来换取安全
 * @author vince
 *
 */
public class ThreadDemo2 {


public static void main(String[] args) {
MyThread my = new MyThread();
Thread t1 = new Thread(my);
Thread t2 = new Thread(my);


t1.start();
t2.start();
}


static class MyThread implements Runnable {
private int flag;//
private Object obj = new Object();


@Override
public void run() {
//同步代码块
synchronized (obj) {
for (int i = 0; i < 5; i++) {
flag = 0;
System.out.println("开始打饭-" + flag);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
flag = 1;
System.out.println("饭已打完-" + flag);
}
}
}

//同步方法:同步的锁对象是当前对象
public synchronized void eat(){
for (int i = 0; i < 5; i++) {
flag = 0;
System.out.println("开始打饭-" + flag);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
flag = 1;
System.out.println("饭已打完-" + flag);
}
}
public synchronized void method2(){
System.out.println("method2...");
}
//互斥锁
private final ReentrantLock lock = new ReentrantLock();
public void eat2(){
lock.lock();//上锁

for (int i = 0; i < 5; i++) {
flag = 0;
System.out.println("开始打饭-" + flag);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
flag = 1;
System.out.println("饭已打完-" + flag);
}

lock.unlock();//解锁


}
}
}

4.中断线程,往往可以自己定义boolean,来加以控制判断

package com.vince;


//中断线程:自定义标记
public class ThreadDemo3 {


public static void main(String[] args) throws InterruptedException {


MyThread my = new MyThread();
Thread t1 = new Thread(my);
t1.start();
// t1.stop();//停止
for (int i = 0; i < 10; i++) {
Thread.sleep(500);

}
my.flag = false;

}


static class MyThread implements Runnable{

public boolean flag;
public MyThread(){
flag = true;
}
@Override
public void run() {
int i = 0;
while(flag) {
System.out.println("i="+i);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
i++;
if(i==100)break;//退出循环
}
}
}
}

4、死锁

同步多了就容易死锁,就像堵车一样互不让路,这样就一直堵在那里。

具体实例如下

package com.vince;
/**
 * 线程死锁
 * @author vince
 *
 */
public class DeadThreadDemo {


public static void main(String[] args) {
new DeadThread();
}


}


//顾客
class Customer{
public synchronized void say(Waiter w){
System.out.println("顾客说:先吃饭再买单!");
w.doService();
}

public synchronized void doService(){
System.out.println("同意了,买完单再吃饭!");
}
}
//服务员
class Waiter{
public synchronized void say(Customer c){
System.out.println("服务员说:先买单再吃饭!");
c.doService();
}
public synchronized void doService(){
System.out.println("同意了,吃完饭再买单!");
}
}




//死锁线程
class DeadThread implements Runnable{
Customer c = new Customer();
Waiter w = new Waiter();
public DeadThread(){
new Thread(this).start();
w.say(c);
}
@Override
public void run() {
c.say(w);
}
}




5、生产者与消费者应用案例(经典案例)

package com.vince;


/**
 * 生产者与消费者案例
 * @author vince
 *
 */
public class ThreadDemo4 {


public static void main(String[] args) {

Food food = new Food();
Producter p = new Producter(food);
Customers c = new Customers(food);
Thread t1  = new Thread(p);
Thread t2 = new Thread(c);
t1.start();
t2.start();
}
}
//生产者
class Producter implements Runnable{
private Food food;
public Producter(Food food){
this.food = food;
}
@Override
public void run() {
for(int i=0;i<50;i++){
if(i%2==0){
// System.out.println("");
// food.setName("银耳莲子汤");
// try {
// Thread.sleep(500);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
// food.setEfficasy("功效:美容养颜");
food.set("银耳莲子汤", "功效:美容养颜");
}else{
// food.setName("糖醋里脊");
// try {
// Thread.sleep(500);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
// food.setEfficasy("功效:酸甜可口,可增肥");
food.set("糖醋里脊", "功效:酸甜可口,可增肥");
}
}
}
}


//消息者
class Customers implements Runnable{
private Food food;
public Customers(Food food){
this.food = food;
}
@Override
public void run() {
for (int i = 0; i < 50; i++) {
// try {
// Thread.sleep(500);
// } catch (InterruptedException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
// System.out.println(food.getName()+"->"+food.getEfficasy());
food.get();
}
}
}


//消费的对象(数据)
class Food{
private String name;//菜名
private String efficasy;//功效

private boolean flag = true;//true表示可以生产不能消费,false表示可以消费不能生产

public Food() {
super();
}
public Food(String name, String efficasy) {
super();
this.name = name;
this.efficasy = efficasy;
}

//生产产品
public synchronized void set(String name,String efficasy){
//表示不能生产
if(!flag){
try {
this.wait();//当前线程进入等待状态,让出CPU,并释放该监视器上的锁
} catch (InterruptedException e) {
e.printStackTrace();
}
}


this.setName(name);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
this.setEfficasy(efficasy);
flag = false;//表示不能再生产
this.notify();//唤醒该监视器上的其它一个线程
}


public synchronized void get(){

if(flag){
try {
this.wait();//
} catch (InterruptedException e) {
e.printStackTrace();
}
}

try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(this.getName()+"->"+this.getEfficasy());
flag = true;//表示不能再取
this.notify();//唤醒该监视器上的其它一个线程
}


public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEfficasy() {
return efficasy;
}
public void setEfficasy(String efficasy) {
this.efficasy = efficasy;
}
}

















6、线程池 

package com.vince;


import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;


public class ExecutorDemo {


public static void main(String[] args) {
//创建一个单线程的执行器
// ExecutorService es = Executors.newSingleThreadExecutor();
//创建一个固定数量的线程执行器
// ExecutorService es = Executors.newFixedThreadPool(3);
//创建一个可缓存线程的执行器(60秒空间将被回收)
ExecutorService es = Executors.newCachedThreadPool();
// ExecutorService es = Executors.newScheduledThreadPool(3);
es.execute(new DownloadThread());
es.execute(new DownloadThread());
es.execute(new DownloadThread());
es.execute(new DownloadThread());

}


static class DownloadThread implements Runnable{
@Override
public void run() {

for (int i = 0; i <= 10; i++) {
System.out.println(Thread.currentThread().getName()+"已下载"+(i*10)+"%");
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}

}
}


}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
完整版:https://download.csdn.net/download/qq_27595745/89522468 【课程大纲】 1-1 什么是java 1-2 认识java语言 1-3 java平台的体系结构 1-4 java SE环境安装和配置 2-1 java程序简介 2-2 计算机中的程序 2-3 java程序 2-4 java类库组织结构和文档 2-5 java虚拟机简介 2-6 java的垃圾回收器 2-7 java上机练习 3-1 java语言基础入门 3-2 数据的分类 3-3 标识符、关键字和常量 3-4 运算符 3-5 表达式 3-6 顺序结构和选择结构 3-7 循环语句 3-8 跳转语句 3-9 MyEclipse工具介绍 3-10 java基础知识章节练习 4-1 一维数组 4-2 数组应用 4-3 多维数组 4-4 排序算法 4-5 增强for循环 4-6 数组和排序算法章节练习 5-0 抽象和封装 5-1 面向过程的设计思想 5-2 面向对象的设计思想 5-3 抽象 5-4 封装 5-5 属性 5-6 方法的定义 5-7 this关键字 5-8 javaBean 5-9 包 package 5-10 抽象和封装章节练习 6-0 继承和多态 6-1 继承 6-2 object类 6-3 多态 6-4 访问修饰符 6-5 static修饰符 6-6 final修饰符 6-7 abstract修饰符 6-8 接口 6-9 继承和多态 章节练习 7-1 面向对象的分析与设计简介 7-2 对象模型建立 7-3 类之间的关系 7-4 软件的可维护与复用设计原则 7-5 面向对象的设计与分析 章节练习 8-1 内部类与包装器 8-2 对象包装器 8-3 装箱和拆箱 8-4 练习题 9-1 常用类介绍 9-2 StringBuffer和String Builder类 9-3 Rintime类的使用 9-4 日期类简介 9-5 java程序国际化的实现 9-6 Random类和Math类 9-7 枚举 9-8 练习题 10-1 java异常处理 10-2 认识异常 10-3 使用try和catch捕获异常 10-4 使用throw和throws引发异常 10-5 finally关键字 10-6 getMessage和printStackTrace方法 10-7 异常分类 10-8 自定义异常类 10-9 练习题 11-1 Java集合框架和泛型机制 11-2 Collection接口 11-3 Set接口实现类 11-4 List接口实现类 11-5 Map接口 11-6 Collections类 11-7 泛型概述 11-8 练习题 12-1 多线程 12-2 线程的生命周期 12-3 线程的调度和优先级 12-4 线程的同步 12-5 集合类的同步问题 12-6 用Timer类调度任务 12-7 练习题 13-1 Java IO 13-2 Java IO原理 13-3 流类的结构 13-4 文件流 13-5 缓冲流 13-6 转换流 13-7 数据流 13-8 打印流 13-9 对象流 13-10 随机存取文件流 13-11 zip文件流 13-12 练习题 14-1 图形用户界面设计 14-2 事件处理机制 14-3 AWT常用组件 14-4 swing简介 14-5 可视化开发swing组件 14-6 声音的播放和处理 14-7 2D图形的绘制 14-8 练习题 15-1 反射 15-2 使用Java反射机制 15-3 反射与动态代理 15-4 练习题 16-1 Java标注 16-2 JDK内置的基本标注类型 16-3 自定义标注类型 16-4 对标注进行标注 16-5 利用反射获取标注信息 16-6 练习题 17-1 顶目实战1-单机版五子棋游戏 17-2 总体设计 17-3 代码实现 17-4 程序的运行与发布 17-5 手动生成可执行JAR文件 17-6 练习题 18-1 Java数据库编程 18-2 JDBC类和接口 18-3 JDBC操作SQL 18-4 JDBC基本示例 18-5 JDBC应用示例 18-6 练习题 19-1 。。。
完整版:https://download.csdn.net/download/qq_27595745/89522468 【课程大纲】 1-1 什么是java 1-2 认识java语言 1-3 java平台的体系结构 1-4 java SE环境安装和配置 2-1 java程序简介 2-2 计算机中的程序 2-3 java程序 2-4 java类库组织结构和文档 2-5 java虚拟机简介 2-6 java的垃圾回收器 2-7 java上机练习 3-1 java语言基础入门 3-2 数据的分类 3-3 标识符、关键字和常量 3-4 运算符 3-5 表达式 3-6 顺序结构和选择结构 3-7 循环语句 3-8 跳转语句 3-9 MyEclipse工具介绍 3-10 java基础知识章节练习 4-1 一维数组 4-2 数组应用 4-3 多维数组 4-4 排序算法 4-5 增强for循环 4-6 数组和排序算法章节练习 5-0 抽象和封装 5-1 面向过程的设计思想 5-2 面向对象的设计思想 5-3 抽象 5-4 封装 5-5 属性 5-6 方法的定义 5-7 this关键字 5-8 javaBean 5-9 包 package 5-10 抽象和封装章节练习 6-0 继承和多态 6-1 继承 6-2 object类 6-3 多态 6-4 访问修饰符 6-5 static修饰符 6-6 final修饰符 6-7 abstract修饰符 6-8 接口 6-9 继承和多态 章节练习 7-1 面向对象的分析与设计简介 7-2 对象模型建立 7-3 类之间的关系 7-4 软件的可维护与复用设计原则 7-5 面向对象的设计与分析 章节练习 8-1 内部类与包装器 8-2 对象包装器 8-3 装箱和拆箱 8-4 练习题 9-1 常用类介绍 9-2 StringBuffer和String Builder类 9-3 Rintime类的使用 9-4 日期类简介 9-5 java程序国际化的实现 9-6 Random类和Math类 9-7 枚举 9-8 练习题 10-1 java异常处理 10-2 认识异常 10-3 使用try和catch捕获异常 10-4 使用throw和throws引发异常 10-5 finally关键字 10-6 getMessage和printStackTrace方法 10-7 异常分类 10-8 自定义异常类 10-9 练习题 11-1 Java集合框架和泛型机制 11-2 Collection接口 11-3 Set接口实现类 11-4 List接口实现类 11-5 Map接口 11-6 Collections类 11-7 泛型概述 11-8 练习题 12-1 多线程 12-2 线程的生命周期 12-3 线程的调度和优先级 12-4 线程的同步 12-5 集合类的同步问题 12-6 用Timer类调度任务 12-7 练习题 13-1 Java IO 13-2 Java IO原理 13-3 流类的结构 13-4 文件流 13-5 缓冲流 13-6 转换流 13-7 数据流 13-8 打印流 13-9 对象流 13-10 随机存取文件流 13-11 zip文件流 13-12 练习题 14-1 图形用户界面设计 14-2 事件处理机制 14-3 AWT常用组件 14-4 swing简介 14-5 可视化开发swing组件 14-6 声音的播放和处理 14-7 2D图形的绘制 14-8 练习题 15-1 反射 15-2 使用Java反射机制 15-3 反射与动态代理 15-4 练习题 16-1 Java标注 16-2 JDK内置的基本标注类型 16-3 自定义标注类型 16-4 对标注进行标注 16-5 利用反射获取标注信息 16-6 练习题 17-1 顶目实战1-单机版五子棋游戏 17-2 总体设计 17-3 代码实现 17-4 程序的运行与发布 17-5 手动生成可执行JAR文件 17-6 练习题 18-1 Java数据库编程 18-2 JDBC类和接口 18-3 JDBC操作SQL 18-4 JDBC基本示例 18-5 JDBC应用示例 18-6 练习题 19-1 。。。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值