java 多线程1、进程,在我们的操作系统中,没打开一个软件,就占有系统一个进程,来执行这个软件的程序。
2、进程,一次程序整体执行就是一个进程。
3、线程,一个进程中的多个分支,每一个分子程序就是一个线程。
4、不管是多进程还是多线程,都是为了同时可以完成多任务操作。
5、对操作系统来讲,支持多任务,起多个进程代表系统中的多个应用程序。
6、在每一个应用程序中,起多个线程代表了,每个线程代表了一个任务。
7、java 应用程序针对多任务就是使用多线程来完成的。
8、在平时所写的代码,都是java 的单线程程序,都是从上往下执行,从主函数开始执行,调用一个方法
这个方法执行完毕,下一行代码才可以执行,把这个从main 函数开始执行的程序叫主线程。
9、创建线程类的方式:
a、继承Thread 类 b、实现Runnable 接口
10、根据我们创建线程类型,创建线程对象(线程)
a、MyThread mt = new MyThread(); MyThread mt2 = new MyThread();
b、MyRunnable mr = new MyRunnable();
Thread t = new Thread(mr);
11、启动线程, 调用线程对象的start(); Thread 类中给我们提供好的。
调用完start 方法 ,这个是处于准备运行状态,直到cpu有空闲时间就可以运行。
12、进程和线程的区别?
进程:每个进程都有独立的代码和数据空间(进程上下文),进程间的切换会有较大的开销,一个进程包含1--n个线程。
线程:同一类线程共享代码和数据空间,每个线程有独立的运行栈和程序计数器(PC),线程切换开销小。
线程和进程一样分为五个阶段:创建、就绪、运行、阻塞、终止。
多进程是指操作系统能同时运行多个任务(程序)。
多线程是指在同一程序中有多个顺序流在执行。
顺序流指线程代码中run方法开始,从上往下执行的过程。run 方法就是一个线程的开始
13、Thread和Runnable 的区别?资源能不能共享的问题。
Thread 类是Runnable 接口实现类。 (建议使用Runnable 来创建线程类,这样有利于扩展和资源共享)
如果一个类继承Thread,则不适合资源共享(加上一个线程同步也可以实现资源共享)。
但是如果实现了Runable接口的话,则很容易的实现资源共享。
实现Runnable接口比继承Thread类所具有的优势:
1):适合多个相同的程序代码的线程去处理同一个资源
2):可以避免java中的单继承的限制
3):增加程序的健壮性,代码可以被多个线程共享,代码和数据独立
如果是针对静态变量的话,Thread 还是Runnable ,都是共享的。
如果是非静态变量runnable 是可以共享的,但是线程对象必须是同一个。
14、线程状态(初始状态,可运行(就绪状态、准备状态),运行,阻塞,死亡(停止))
15、利用线程中给我们提供的操作方法,实现线程状态变化,这叫线程调度。
16、线程同步 线程死锁 线程通信
package com.salmon.test;
/**
* 创建了一个 线程类型
* @author salmon
*
*/
public class MyThread extends Thread {
/**
* 重写Thread 类中一个 run 方法
*
* 这个方法就负责 这个中类型的线程 今后要做的事情
*/
public void run(){
int i = 0;
while(true){
System.out.println(this.getName()+i++);
// 让我们的当前子线程 每隔一秒钟 执行一次
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
package com.salmon.test;
/**
* 实现接口 来实现的线程类
* @author salmon
*
*/
public class MyThread2 implements Runnable {
@Override
public void run() {
int i = 0;
while(true){
// 得到当前线程名称
System.out.println(Thread.currentThread().getName()+"---"+i++);
// 让我们的当前子线程 每隔一秒钟 执行一次
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
package com.salmon.test;
/**
* 一个程序 带有main 函数的是一个 主线程
* @author salmon
*
*/
public class Test {
public static void main(String[] args) {
/*int i = 0;
while(true){
System.out.println(i++);
}*/
// 创建一个线程
MyThread mt = new MyThread();
// 设置线程名称
mt.setName("zhangsan");
// 启动线程 调用线程对象的start 方法 ,一旦有空闲时间 线程中run 方法就自动被执行
mt.start();
// 以下代码 就是我们这个当前主线程中程序
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("hello");
//
MyThread mt2 = new MyThread();
mt2.setName("wangwu");
mt2.start();
}
}
package com.salmon.test;
public class Test2 {
public static void main(String[] args) {
// 创建线程
MyThread2 mt = new MyThread2();
// 启动线程 借助于Thread 来启动
Thread t = new Thread(mt,"t1");
//t.setName("t1");
t.start();
// 创建线程
MyThread2 mt2 = new MyThread2();
// 启动线程 借助于Thread 来启动
Thread t2 = new Thread(mt,"t2");
//t2.setName("t2");
t2.start();
//
System.out.println("hello");
}
}