并发编程:Thread和Runable-01
1.继承Thread类(不推荐)
代码很简单,就不说了
public class ThreadTest02 {
public static void main(String[] args) {
new UserThread("A").start();
System.out.println("结束。。。");
}
public static class UserThread extends Thread {
UserThread(String name) {
this.setName(name);
}
public void run() {
System.out.println(Thread.currentThread().getName() + " run方法执行了。。。");
}
}
}
2.实现Runable接口
public class RunableTest01 {
public static void main(String[] args) {
Thread thread = new Thread(new UserThread(), "A");
thread.start();
System.out.println("结束。。。");
}
public static class UserThread implements Runnable {
public void run() {
System.out.println(Thread.currentThread().getName() + " run方法执行了");
}
}
}
以上运行的结果:
结束。。。
A run方法执行了
run和start的区别?
- start()它的作用是启动一个新线程。通过start()方法来启动的新线程,处于就绪(可运行)状态,并没有运行,一旦得到cpu时间片,就开始执行相应线程的run()方法,这里方法run()称为线程体,它包含了要执行的这个线程的内容,run方法运行结束,此线程随即终止。start()不能被重复调用。用start方法来启动线程,真正实现了多线程运行,即无需等待某个线程的run方法体代码执行完毕就直接继续执行下面的代码。这里无需等待run方法执行完毕,即可继续执行下面的代码,即进行了线程切换。
- run()就和普通的成员方法一样,可以被重复调用。如果直接调用run方法,并不会启动新线程!程序中依然只有主线程这一个线程,其程序执行路径还是只有一条,还是要顺序执行,还是要等待run方法体执行完毕后才可继续执行下面的代码,这样就没有达到多线程的目的。总结:调用start方法方可启动线程,而run方法只是thread的一个普通方法调用,还是在主线程里执行。
数据共享与非共享
1.数据不共享
新起三个不同的线程,对成员变量操作,互不影响
public class ThreadShareTest01 {
public static void main(String[] args) {
Thread thread1 = new Thread(new UserThread(), "A");
Thread thread2 = new Thread(new UserThread(), "B");
Thread thread3 = new Thread(new UserThread(), "C");
thread1.start();
thread2.start();
thread3.start();
}
public static class UserThread extends Thread {
private int count = 10;
public void run() {
while (count > 0) {
count--;
System.out.println(Thread.currentThread().getName() + " 线程过来了,count变为:" + count);
}
System.out.println("count小于0了");
}
}
}
结果:
A 线程过来了,count变为:9
A 线程过来了,count变为:8
A 线程过来了,count变为:7
A 线程过来了,count变为:6
A 线程过来了,count变为:5
A 线程过来了,count变为:4
A 线程过来了,count变为:3
A 线程过来了,count变为:2
A 线程过来了,count变为:1
A 线程过来了,count变为:0
count小于0了
B 线程过来了,count变为:9
B 线程过来了,count变为:8
B 线程过来了,count变为:7
B 线程过来了,count变为:6
B 线程过来了,count变为:5
B 线程过来了,count变为:4
B 线程过来了,count变为:3
B 线程过来了,count变为:2
B 线程过来了,count变为:1
B 线程过来了,count变为:0
count小于0了
C 线程过来了,count变为:9
C 线程过来了,count变为:8
C 线程过来了,count变为:7
C 线程过来了,count变为:6
C 线程过来了,count变为:5
C 线程过来了,count变为:4
C 线程过来了,count变为:3
C 线程过来了,count变为:2
C 线程过来了,count变为:1
C 线程过来了,count变为:0
count小于0了
2.数据共享
public class ThreadShareTest02 {
public static void main(String[] args) {
UserThread userThread = new UserThread();
Thread thread1 = new Thread(userThread, "A");
Thread thread2 = new Thread(userThread, "B");
Thread thread3 = new Thread(userThread, "C");
Thread thread4 = new Thread(userThread, "D");
Thread thread5 = new Thread(userThread, "E");
Thread thread6 = new Thread(userThread, "F");
Thread thread7 = new Thread(userThread, "G");
Thread thread8 = new Thread(userThread, "H");
Thread thread9 = new Thread(userThread, "I");
Thread thread10 = new Thread(userThread, "J");
thread1.start();
thread2.start();
thread3.start();
thread4.start();
thread5.start();
thread6.start();
thread7.start();
thread8.start();
thread9.start();
thread10.start();
}
public static class UserThread extends Thread {
private int count = 10;
public void run() {
count--;
System.out.println(Thread.currentThread().getName() + " 线程过来了,count变为:" + count);
}
}
}
结果:
有问题了!
A 线程过来了,count变为:8
B 线程过来了,count变为:8
C 线程过来了,count变为:7
E 线程过来了,count变为:5
D 线程过来了,count变为:5
J 线程过来了,count变为:3
G 线程过来了,count变为:3
F 线程过来了,count变为:2
I 线程过来了,count变为:1
H 线程过来了,count变为:0
解决办法?
最简单的是在run方法加上synchronized,其实还有别的更高效的方法,后面会说到
public synchronized void run() {
count--;
System.out.println(Thread.currentThread().getName() + " 线程过来了,count变为:" + count);
}
改善结果:
A 线程过来了,count变为:9
B 线程过来了,count变为:8
D 线程过来了,count变为:7
E 线程过来了,count变为:6
C 线程过来了,count变为:5
G 线程过来了,count变为:4
H 线程过来了,count变为:3
I 线程过来了,count变为:2
J 线程过来了,count变为:1
F 线程过来了,count变为:0
ok!
并发编程:Thread和Runable-01的更多相关文章
- java 并发编程——Thread 源码重新学习
Java 并发编程系列文章 Java 并发基础——线程安全性 Java 并发编程——Callable+Future+FutureTask java 并发编程——Thread 源码重新学习 java并发 ...
- Java并发编程-Thread类的使用
在前面2篇文章分别讲到了线程和进程的由来.以及如何在Java中怎么创建线程和进程.今天我们来学习一下Thread类,在学习Thread类之前,先介绍与线程相关知识:线程的几种状态.上下文切换,然后接着 ...
- C++并发编程 thread
std::thread C++11在标准库中为多线程提供组件, 使用线程需要包含头文件 thread, 其命名空间为 std. 启动新线程 每个进程至少有一个线程: 执行main()函数的线程, 其余 ...
- Java 并发编程:Callable和Future
项目中经常有些任务需要异步(提交到线程池中)去执行,而主线程往往需要知道异步执行产生的结果,这时我们要怎么做呢?用runnable是无法实现的,我们需要用callable实现. import java ...
- Java 并发编程——Callable+Future+FutureTask
Java 并发编程系列文章 Java 并发基础——线程安全性 Java 并发编程——Callable+Future+FutureTask java 并发编程——Thread 源码重新学习 java并发 ...
- Java并发编程(08):Executor线程池框架
本文源码:GitHub·点这里 || GitEE·点这里 一.Executor框架简介 1.基础简介 Executor系统中,将线程任务提交和任务执行进行了解耦的设计,Executor有各种功能强大的 ...
- Java 并发编程——Executor框架和线程池原理
Eexecutor作为灵活且强大的异步执行框架,其支持多种不同类型的任务执行策略,提供了一种标准的方法将任务的提交过程和执行过程解耦开发,基于生产者-消费者模式,其提交任务的线程相当于生产者,执行任务 ...
- java并发编程——通过ReentrantLock,Condition实现银行存取款
java.util.concurrent.locks包为锁和等待条件提供一个框架的接口和类,它不同于内置同步和监视器.该框架允许更灵活地使用锁和条件,但以更难用的语法为代价. Lock 接口 ...
- Java并发编程——BlockingQueue
简介 BlockingQueue很好的解决了多线程中,如何高效安全"传输"数据的问题.通过这些高效并且线程安全的队列类,为我们快速搭建高质量的多线程程序带来极大的便利. 阻塞队列是 ...
随机推荐
- Mysql 排序优化
原文链接:https://www.cnblogs.com/moss_tan_jun/p/6021822.html https://blog.csdn.net/lb517290079/article/d ...
- Python 环境搭建(Win 安装以及Mac OS 安装)
千里之行始于足下,今天我们先来学习 Python 环境搭建. 注意:本系列教程基于 Python 3.X Python 环境搭建 Win 安装 打开 Python 官网 https://www.pyt ...
- 基因id转换
DAVID网站提供了id转换的功能 1 选择上传gene list文件 2 选择上传ID的类型,我们ID-list.txt中的是Ensembl Gene ID,所以这里选ENSEMBL_GENE_ID ...
- Go资源被墙最快解决方案
原文链接:https://juejin.im/post/5cd945946fb9a032060c47a3,补充,最新的1.13版本go里默认就是用go module,直接设置代理即可: 注:如果没法升 ...
- QT http请求数据
1.创建一个请求类(HttpWork): HttpWork.h头文件 #pragma once #include <QObject> #include <QNetworkAccess ...
- python 的django项目复制方法
python 的django项目复制方法 django_pyecharts_1修改为django_pyecharts_1_cs1.拷贝项目(确保原有项目是关闭状态下)2.粘贴项目并删除idea文件夹和 ...
- python 之 网络编程(基于UDP协议的套接字通信)
8.5 基于UDP协议的套接字通信 UDP协议:数据报协议 特点:无连接,一发对应一收,先启动哪一端都不会报错 优点:发送效率高,但有效传输的数据量最多为500bytes 缺点:不可靠:发送数据,无需 ...
- golang之 iota 常量生成器
常量声明可以使用iota常量生成器初始化,它用于生成一组以相似规则初始化的常量,但是不用每行都写一遍初始化表达式.在一个const声明语句中,在第一个声明的常量所在的行,iota将会被置为0,然后在每 ...
- C++11 特性
之前工作中开发/维护的模块大多都是 "远古代码",只能编译 C++98,很多 C++11 的特性都忘得差不多了,再回顾一下 右值引用&转移语义: 消除两个对象交互时不必要的 ...
- Mongodb命令行导入导出数据
第一步,找到mongodb安装目录第二步,从命令行进入mongodb安装目录下的bin目录第三步(1),导出数据命令(导出的文件有两种格式:json/csv,此处导出的是json文件,对于导出CSV文 ...