Java多线程基础(一)

1.什么是进程、线程

  进程可以简单的理解为应用程序。多线程,相当于多个人共同完成一件事情,每个线程,独立完成一件任务。因此,一个进程至少有一个线程,一个线程不能独立存在,它必须是进程的一部分。

  进程:每个独立运行着的程序。具有独立的内存空间和系统资源。(建大厦)

  线程:是一个进程内部的一条执行路径。是系统独立调度和分配CPU的最小单位。(搬砖头)

2.创建线程的方式(三种)

  • 1.通过实现 Runnable 接口;(存在共享资源时使用——是否是相同操作)
  • 2.通过继承 Thread 类本身;(没有共享资源时可用)
  • 3.通过 Callable 和 Future 创建线程。(JDK1.5开始引入)

    对比:

  • 1. 采用实现 Runnable、Callable 接口的方式创建多线程时,线程类只是实现了 Runnable 接口或 Callable 接口,还可以继承其他类。

  • 2. 使用继承 Thread 类的方式创建多线程时,编写简单,如果需要访问当前线程,则无需使用 Thread.currentThread() 方法,直接使用 this 即可获得当前线程。

3.线程的状态及特性

线程具有随机性:谁能抢到CPU,谁执行。 

package com.test;
public class ThreadDemo1 { public static void main(String[] args) { // TODO Auto-generated method stub MyThread myThread=new MyThread("name"); //myThread.run();//主线程 myThread.start();//多线程 } } class MyThread extends Thread{ public MyThread() { super(); // TODO Auto-generated constructor stub } public MyThread(String name) { super(name); } public void run() { for(int i=0;i<20;i++) { System.out.println(Thread.currentThread().getName()+"→"+i); } } }

创建线程,输出1~100之间的偶数。要求使用线程实现,继承Thread类

package com.test;

public class ThreadDemo2 {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        OutputEven outputEven=new OutputEven();
        outputEven.start();
    }

}
class OutputEven extends Thread{

    @Override
    public void run() {
        // TODO Auto-generated method stub
        for(int i=1;i<=100;i++) {
            if(i%2==0) {
                System.out.println(Thread.currentThread().getName()+"→"+i);
            }
        }
    }
    
}

 使用线程模拟四个工人搬砖场景,谁抢到托运机谁去搬砖

package com.test;

public class ThreadDemo3 {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Worker worker1=new Worker("张三1","搬砖");
        Worker worker2=new Worker("张三2","搬砖");
        Worker worker3=new Worker("张三3","搬砖");
        Worker worker4=new Worker("张三4","搬砖");
        worker1.start();
        worker2.start();
        worker3.start();
        worker4.start();
        
    }

}
class Worker extends Thread{
    String name;
    String task;
    
    public Worker() {
        // TODO Auto-generated constructor stub
        super();
    }
    
    public Worker(String name, String task) {
        super();
        this.name = name;
        this.task = task;
    }

    @Override
    public void run() {
        // TODO Auto-generated method stub
        work();
    }
    public void work() {
        System.out.println(name+"正在"+task);
    }
}

三个窗口都可以卖100张票。

package com.test;

public class ThreadDemo4 {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        WinTicket winTicket1=new WinTicket("窗口1");
        WinTicket winTicket2=new WinTicket("窗口2");
        WinTicket winTicket3=new WinTicket("窗口3");
        winTicket1.start();
        winTicket2.start();
        winTicket3.start();
        
    }

}
class WinTicket extends Thread{
    private int ticket=100;

    public WinTicket() {
        super();
        // TODO Auto-generated constructor stub
    }
    public WinTicket(String name) {
        super(name);
    }
    @Override
    public void run() {
        // TODO Auto-generated method stub
        while(true) {
            if(ticket>0) {
                String name=Thread.currentThread().getName();
                System.out.println(name+"卖出"+ticket--);
            }else {
                break;
            }
        }
    }
    
} 

 4.多个线程共享资源

  三个窗口共同卖100张票。

package com.test;

public class ThreadDemo5 {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        //创建共享资源对象
        TicketRes ticketRes=new TicketRes();
        //创建线程对象
        Thread w1=new Thread(ticketRes,"窗口1");
        Thread w2=new Thread(ticketRes,"窗口2");
        Thread w3=new Thread(ticketRes,"窗口3");
        w1.start();
        w2.start();
        w3.start();
    }
}
//共享资源类
class TicketRes implements Runnable{
    private int ticket=100;
    
    @Override
    public void run() {
        // TODO Auto-generated method stub
        while(true) {
            if(ticket>=1) {
                System.out.println(Thread.currentThread().getName()+"卖第"+ticket+"张票");
                ticket--;
            }else {
                break;
            }
        }
    }
}
//出现一个问题:第一百张票会同时在三个窗口卖出。这个涉及到同步和异步的问题?该怎么解决呢?Java多线程基础(二)揭晓答案

5.线程调度

优先级 

  优先级用1-10表示,1的优先级最低,10的优先级最高,默认情况为5

  setPriority(int grade);

调度方法

  join():阻塞指定的线程等到另一个线程完成以后再执行 

package com.test;

public class JoinDemo {

    public static void main(String[] args) throws InterruptedException {
        // TODO Auto-generated method stub
        System.out.println("主线程在执行...");
        JoinThread joinThread1=new JoinThread("线程1");
        JoinThread joinThread2=new JoinThread("线程2");
        JoinThread joinThread3=new JoinThread("线程3");
        System.out.println("启动子线程...");
        joinThread1.start();
        joinThread2.start();
        joinThread3.start();
        joinThread1.join();
        joinThread2.join();
        joinThread3.join();
        for(int i=0;i<10;i++) {
            System.out.println("主线程正在执行...");
        }
        System.out.println("结束");
    }
    

}
class JoinThread extends Thread{
    
    public JoinThread() {
        super();
        // TODO Auto-generated constructor stub
    }
    
    public JoinThread(String name) {
        super(name);
        // TODO Auto-generated constructor stub
    }

    @Override
    public void run() {
        // TODO Auto-generated method stub
        for(int i=0;i<10;i++) {
            System.out.println(Thread.currentThread().getName()+"→"+i);
        }
    }
    
}
View Code

  sleep():会暂时释放CPU, 让给其他线程执行, 即使没有其他线程抢占CPU,也需要等待睡眠时间到了以后才能真正的指定

package com.test;

public class SleepDemo {

    public static void main(String[] args){
        // TODO Auto-generated method stub
        SleepThread sleepThread=new SleepThread();
        sleepThread.start();
    }

}
class SleepThread extends Thread{
    
    public SleepThread() {
        super();
        // TODO Auto-generated constructor stub
    }
    
    public SleepThread(String name) {
        super(name);
        // TODO Auto-generated constructor stub
    }

    @Override
    public void run() {
        // TODO Auto-generated method stub
        for(int i=10;i>=0;i--) {
            try {
                Thread.sleep(1000);
                System.out.println(i);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
    
}
View Code

  yield():执行的时候会让出CPU , 但是会立马同其他的线程抢占CPU

package com.test;

public class YieldDemo {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        YieldThread yieldThread1=new YieldThread("线程1");
        YieldThread yieldThread2=new YieldThread("线程2");
        yieldThread1.start();
        yieldThread2.start();
    }

}
class YieldThread extends Thread{
    
    public YieldThread() {
        super();
        // TODO Auto-generated constructor stub
    }
    
    public YieldThread(String name) {
        super(name);
        // TODO Auto-generated constructor stub
    }

    @Override
    public void run() {
        // TODO Auto-generated method stub
        for(int i=0;i<20;i++) {
            System.out.println(Thread.currentThread().getName()+"→"+i);
            Thread.yield();//避让,谦让,让出CPU,还有再去抢的资格
        }
    }
    
}
View Code
原文地址:https://www.cnblogs.com/loober/p/10193332.html