并发编程: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很好的解决了多线程中,如何高效安全"传输"数据的问题.通过这些高效并且线程安全的队列类,为我们快速搭建高质量的多线程程序带来极大的便利. 阻塞队列是 ...
随机推荐
- git的基本使用流程
1. 在远端创建代码仓库 2. 拉取到本地 git clone $(path) #其中,path包括git路径或者https路径,可通过实际情况进行拉取.另外,可通过-b参数指定拉取的分支,默认拉取m ...
- Python 机器学习库 NumPy 教程
0 Numpy简单介绍 Numpy是Python的一个科学计算的库,提供了矩阵运算的功能,其一般与Scipy.matplotlib一起使用.其实,list已经提供了类似于矩阵的表示形式,不过numpy ...
- LeetCode 718. 最长重复子数组(Maximum Length of Repeated Subarray)
718. 最长重复子数组 718. Maximum Length of Repeated Subarray 题目描述 给定一个含有 n 个正整数的数组和一个正整数 s,找出该数组中满足其和 ≥ s 的 ...
- 014 Android 自定义组合控件
1.需求介绍 将已经编写好的布局文件,抽取到一个类中去做管理,下次还需要使用类似布局时,直接使用该组合控件的对象. 优点:可复用. 例如要重复利用以下布局: <RelativeLayout an ...
- [转帖]libev与libuv的区别
libev与libuv的区别 https://www.cnblogs.com/charlesblc/p/6341280.html 参考: http://blog.csdn.net/w616589292 ...
- 【转帖】K8S Deployment 命令
K8S Deployment 命令 https://www.cnblogs.com/Tempted/p/7831604.html 今天学习了一下 kubectl scale deployment xx ...
- redis 主从 哨兵
数据库为什么要读写分离 写代码好多年了,大家先抛弃在代码框架里面各种花哨的设计之外,写的代码到最后无非就是为了增删查改数据库.一般项目数据库刚开始只是但一个库,随着数据量的增大,就开始优化数据库(抛开 ...
- sqlserve 数据库8G log文件也有10来g 按日期删除 方法
数据库存了几年的数据没有维护过,数据庞大,日志文件也不小,如何清理不需要的数据呢 首先考虑的肯定是某个日期之前的数据清除掉 delete from 表名 where cast(字段名 as datet ...
- Ubuntu 更换下载源
Ubuntu将下载官方源更换为国内源 由于某些原因,在国内更新软件都很慢,可以改源为国内源 1.备份原始文件 sudo cp /etc/apt/sources.list /etc/apt/source ...
- C++ 用 vector 生成三维数组,并计算行、列、高
//Microsoft Visual Studio 2015 Enterprise //用vector生成三维数组,并计算行.列.高 #include <iostream> #includ ...