java 多线程
2019-03-28 本文已影响0人
会摄影的程序员
[TOC]
1 多线程demo
code
public class MyThredDo {
public static class MyThred extends Thread{
@Override
public void run() {
for (int i = 0; i < 20; i++) {
try {
Thread.sleep(20);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("run: "+ i);
}
}
}
public static void main(String[] args) throws InterruptedException {
MyThred myThred = new MyThred();
myThred.start();
for (int i = 0; i < 20; i++) {
Thread.sleep(20);
System.out.println("main:" +i);
}
}
}
运行结果:
main:0
run: 0
main:1
run: 1
main:2
run: 2
main:3
run: 3
main:4
run: 4
main:5
run: 5
main:6
run: 6
main:7
run: 7
main:8
run: 8
run: 9
main:9
main:10
run: 10
main:11
run: 11
run: 12
main:12
main:13
run: 13
run: 14
main:14
main:15
run: 15
run: 16
main:16
run: 17
main:17
run: 18
main:18
run: 19
main:19
2 Thread的方法
2.1 获取线程的名字
- 使用Thread类中的方法getName();
String getName(); - 可以获取到当前正在执行的线程,使用线程中的getName()获取线程的名字
static Thread currentThread()返回当前正在执行的线程对象的引用
code:
public class MyGetThreadName {
/**
* 获取线程名称的第一种方式
* @Author chenpeng
* @Description //TODO
* @Date 20:53
* @Param
* @return
**/
public static class GetThreadName1 extends Thread{
@Override
public void run() {
String threadName = getName();
System.out.println(threadName);
}
}
/**
* 获取线程名称的第二种方式
* @Author chenpeng
* @Description //TODO
* @Date 20:58
* @Param
* @return
**/
public static class GetThreadName2 extends Thread{
@Override
public void run() {
Thread thread = Thread.currentThread();
System.out.println(thread.getName());
}
}
public static void main(String[] args){
new GetThreadName1().start();
new GetThreadName1().start();
new GetThreadName2().start();
new GetThreadName2().start();
System.out.println(Thread.currentThread().getName());
}
}
2.2 设置线程的名字
- 使用Thread中的方法setName
- 创建一个带参数的构造方法,参数传递线程的名称,调用父类的带参构造方法,把线程名传递给父类,让父类给子类线程起一个名字
code:
public class MySetThreadName {
public static class SetThreadName extends Thread{
public SetThreadName() { }
public SetThreadName(String threadName){
super(threadName);
}
@Override
public void run() {
System.out.println(Thread.currentThread().getName());
}
}
public static void main(String[] args){
//第一种设置线程名字的方法
SetThreadName setThreadName = new SetThreadName();
setThreadName.setName("1号线程");
setThreadName.start();
//第二种设置线程名字的方法
new SetThreadName("二号线程").start();
}
}
2.3 sleep()
Thread.sleep(20);
停止多少毫秒后继续执行
2.4 Runnable接口实现多线程
- 创建一个Runnable接口的实现类
- 在实现类中重写run()方法,设置线程任务
- 创建接口实现类的对象
- 创建一个Thread,将创建的接口实现类传入
- 调用Thread中的start()方法,开启新的线程的run方法
code:
public class MyRunnable {
public static class RunnableImpl implements Runnable{
@Override
public void run() {
for (int i = 0; i < 20; i++) {
System.out.println("run: "+Thread.currentThread().getName()+" "+i);
try {
Thread.sleep(20);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) throws InterruptedException {
RunnableImpl runnable = new RunnableImpl();
Thread thread = new Thread(runnable);
thread.start();
for (int i = 0; i < 20; i++) {
System.out.println("run: "+Thread.currentThread().getName()+" "+i);
Thread.sleep(20);
}
}
}
区别
Runnable接口实现多线程的好处
- 避免了只能继承一个类的局限性
- 增强了长须的扩展性,降低了程序的耦合性
实现了Runnable接口的方式,把设置线程任务和开启线程进行了分离(解耦)
2.5 匿名内部类方法实现线程创建
public class InnerClassThread {
public static void main(String[] args){
//继承Thread方法
new Thread(){
@Override
public void run() {
for (int i = 0; i < 20; i++) {
System.out.println(Thread.currentThread().getName()+" "+i);
}
}
}.start();
//调用接口Runnable方法实现
new Thread(new Runnable(){
@Override
public void run() {
for (int i = 0; i < 20; i++) {
System.out.println(Thread.currentThread().getName()+" "+i);
}
}
}).start();
}
}
3 多线程
并发: 两个或多个事件在同一个时间段内发生
交替执行,一个人(CPU)吃两个菜(线程)
并行: 两个或多个事件在同意时刻发生
同时执行,两个人(CPU)吃两个菜(线程)
4 线程与进程
进程:所有的应用程序都需要进入内存中执行。点击应用程序,程序进入内存,进入内存的程序叫进程。
线程:线程属于进程,是进程中的一个执行单元,负责程的执行。是通往cpu的通道。效率高,多个线程之间互不影响。
5 线程调度
- 分时调度
所有线程轮流使用CPU的使用权,平均分配每个线程占用CPU的时间。 - 抢占式调度
优先让优先级高的线程使用CPU,如果线程的优先级相同,呢么就会随机选择一个来执行(线程随机性),java为抢占式调度。