线程
什么是进程
进程就是系统进行资源分配和调用的独立单位,每个进程拥有自己独立的内存空间和系统资源
单进程操作系统和多进程操作系统的区别
dos:单进程操作系统(同一时间只能执行一个进程)
Windows:多进程单用户操作系统(同一时间只允许一个用户执行多个进程)
Linux:多进程多用户操作系统(同一时间允许多个用户执行多个进程)
现在的多核CPU能否让系统在同一时间下执行多个进程
理论上是可以的,但实际上很少这样做
什么是线程,跟进程有什么关系
线程就是进程里面独立单位,一个进程可以有多个线程
关系
进程与进程:两者没有交集,相互独立的存在
线程与线程:两者存在同一个进程时,共享进程的内存空间和系统资源,不是同一个进程时,则没有交集
进程与线程:进程包含线程,线程存在进程中
线程的常见三种创建方法
线程类
public class Test {
public static void main(String[] args) {
//创建线程对象
MyThread mt = new MyThread();
//启动线程
mt.start();
}
}
//写一个线程类
class MyThread extends Thread{
//重写run()方法
@Override
public void run() {
//测试代码块
System.out.println("比心");
}
}
任务类
public class Test {
public static void main(String[] args) {
// 写一个任务类
Thread t = new Thread(new myThread());
//启动线程
t.start();
}
}
//创建任务类
class myThread extends Thread{
@Override
public void run() {
System.out.println("比心");
}
}
带返回值的任务类()
这个用到的是实现接口,而不是继承
public class Test {
public static void main(String[] args) throws Exception {
// 将带有返回值的任务类装载到FutureTask对象中
FutureTask<String> ft = new FutureTask<>(new myThread());
Thread t = new Thread(ft);
t.start();
//获取返回值并输出
String str = ft.get();
System.out.println(str);
}
}
//创建带有返回值的任务类
class myThread implements Callable<String>{
//重写call()方法
@Override
public String call() throws Exception {
System.out.println("比心");
return "比个心";
}
}
直接体会线程之间抢占资源
public class Test {
public static void main(String[] args) {
new Thread(new my())start();
for(int i = 0; i < 100; i++) {
System.out.println("主线程:" + i);
}
}
}
//创建线程
class my extends Thread{
@Override
public void run() {
for(int i = 0; i < 100; i++) {
System.out.println("子线程:" + i);
}
}
}
线程的启动
当存在多个子线程的时候,并不是所有的子线程启动都是要放在主线程中的,某个子线程启动可以嵌套在另一个子线程中,前提是被镶嵌的子线程或其上面子程序有一个是在主线程中,具体看下面代码(仍然是线程之间抢占资源,但是因为输出语句太少,有时候难以直观的体现)
public class Test {
public static void main(String[] args) {
new Thread(new A()).start();
System.out.println("我是主线程");
}
}
class A extends Thread{
@Override
public void run() {
new Thread(new B()).start();
System.out.println("我是A");
}
}
class B extends Thread{
@Override
public void run() {
new Thread(new C()).start();
System.out.println("我是B");
}
}
class C extends Thread{
@Override
public void run() {
System.out.println("我是C");
}
}
设置线程之间的三种优先级别
线程有三个优先级别,但是这三个优先级别只是影响输出结果并不能决定输出结果顺序
public class Test {
public static void main(String[] args) {
//优先级别
D d = new D();
E e = new E();
F f = new F();
d.setPriority(Thread.MAX_PRIORITY); //最高级 -->10
e.setPriority(Thread.NORM_PRIORITY); //默认级 -->5
f.setPriority(Thread.MIN_PRIORITY); //最低级 -->1
d.start();
e.start();
f.start();
for(int i = 0; i < 100; i++) {
System.out.println("我是主线程:" + i);
}
}
}
//创建线程类
class D extends Thread{
@Override
public void run() {
for(int i = 0; i < 100; i++) {
System.out.println("我是D线程:" + i);
}
}
}
class E extends Thread{
@Override
public void run() {
for(int i = 0; i < 100; i++) {
System.out.println("我是E线程:" + i);
}
}
}
class F extends Thread{
@Override
public void run() {
for(int i = 0; i < 100; i++) {
System.out.println("我是F线程:" + i);
}
}
}
线程的取名
当输出的名字不一样,但是线程方法又是相同的时候,就可以用这个来给不同线程取名,达到输出结果仅是名字不同的效果
public class Test {
public static void main(String[] args) {
// 给线程设置名字--是为了实现自己的逻辑
G a = new G("A");
G b = new G("B");
G c = new G("C");
//设置优先级别
a.setPriority(Thread.MAX_PRIORITY);
b.setPriority(Thread.NORM_PRIORITY);
c.setPriority(Thread.NORM_PRIORITY);
//启动线程
a.start();
b.start();
c.start();
}
}
class G extends Thread{
private String threadName; //定义一个线程名字的变量
public G() {
//无参构造
}
public G(String threadName) {
this.threadName = threadName;
}
@Override
public void run() {
for(int i = 0; i < 100; i++) {
System.out.println(this.threadName + ":" + i);
}
}
}
上面的是自己在线程类中定义的名字变量,现在用线程自身带的变量实现同样的效果
public class Test {
public static void main(String[] args) {
myThread a = new myThread("A");
myThread b = new myThread("B");
myThread c = new myThread("C");
a.start();
b.start();
c.start();
}
}
class myThread extends Thread{
public myThread() {
//无参构造
}
public myThread(String threadName) {
super(threadName);
}
@Override
public void run() {
for(int i = 0; i < 100; i++) {
System.out.println(Thread.currentThread().getName() + ":" + i );
}
}
}
稍微了解线程的休眠、礼让、合并
利用倒计时功能来稍微理解下线程休眠状态(sleep)
public class Test {
public static void main(String[] args) {
// 线程的休眠sleep
String[] str = { "A", "B", "C", "D", "E" }; //创建数组并给到值
Random ran = new Random();
int index = ran.nextInt(str.length); //设置生成随机数的范围并赋给变量
for (int i = 3; i > 0; i--) { //设置倒计时的初始值
System.out.println(i);
try {
Thread.sleep(1000); //设置休眠时间为1000毫秒
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(str[index]); //输出随机选出的值
}
}
礼让就是已经抢占到系统资源的线程退出运行状态,然后再次跟其他线程一起去抢占系统资源,礼让的.yield()
放在哪个线程就是那个线程要礼让(可以设置某种要求)
public class Test {
public static void main(String[] args) {
// yield礼让
new Thread(new myThread()).start();
for(int i = 0; i < 100; i++) {
System.out.println("我是主线程:" + i );
}
}
}
class myThread extends Thread{
@Override
public void run() {
for(int i = 0; i < 100; i++) {
System.out.println("我是子线程:" + i );
Thread.yield();
}
}
}
合并.join()
就是让一个线程合并到另一个线程中,所以只能是等前者执行完了才继续执行后者的指令
public class Test11 {
public static void main(String[] args) {
// 合并
Q q = new Q();
P p = new P(q);
q.start();
p.start();
}
}
class Q extends Thread{
@Override
public void run() {
for(int i = 0; i < 100; i++) {
System.out.println("我是q线程:" + i );
}
}
}
class P extends Thread{
private Q q;
public P(Q q) {
this.q = q;
}
@Override
public void run() {
for(int i = 0; i < 100; i++) {
System.out.println("我是p线程:" + i );
if(i == 10) {
try {
q.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
中断线程是中断指令的执行
public class Test12 {
public static void main(String[] args) {
myThread5 mt = new myThread5();
mt.start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
mt.setFlag(false);
}
}
class myThread5 extends Thread{
private boolean flag = true;
public boolean isFlag() {
return flag;
}
public void setFlag(boolean flag) {
this.flag = flag;
}
@Override
public void run() {
while (flag) {
System.out.println("我是A");
System.out.println("我是B");
System.out.println("我是-------------");
}
}
}
中断
ublic class Test13 {
public static void main(String[] args) {
myThread6 mt = new myThread6();
mt.start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
mt.interrupt();
}
}
class myThread6 extends Thread{
@Override
public void run() {
while (!this.isInterrupted()) {
System.out.println("多线程A");
System.out.println("多线程B");
System.out.println("---------------------");
}
}