多线程
什么是多线程:
如果在一个进程中同时运行了多个线程,用来完成不同的工作,则称之为“多线程”
多个线程交替占用CPU资源,而非真正的并行执行
多线程的好处:
充分利用CPU的资源
简化编程模型
带来良好的用户体验
主线程
Thread类:
Java提供了java.lang.Thread类支持多线程编程
主线程:
main()方法即为主线程入口
产生其他子线程的线程
必须最后完成执行,因为它执行各种关闭动作
实例:通过集成Thread类实现创建线程
TestThread类:
package cn.kgc.kb09;
/**
* @Author Daniu_Ben
* @Date 2020/8/5
* @Description
*/
public class TestThread extends Thread{
public void run(){
for (int i = 1; i < 101; i++) {
System.out.println(Thread.currentThread().getName() + ":" + i);
System.out.println("线程休眠,进入堵塞状态");
// try {
// Thread.sleep(10);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
}
}
public static void main(String[] args) {
TestThread t1 = new TestThread();
// t1.setName("线程1");
TestThread t2 = new TestThread();
// t2.setName("线程2");
t1.start();
t2.start();
// TestThread t = new TestThread();
// t.setName("随便啥");
// Thread th1 = new Thread(t);
// th1.setName("设置线程1");
// Thread th2 = new Thread(t);
// th2.setName("设置线程2");
//
// th1.start();
// th2.start();
}
}
通过实现接口Runnable ,创建线程
TeatRunnable类:
package cn.kgc.kb09;
/**
* @Author Daniu_Ben
* @Date 2020/8/5
* @Description
*/
public class TestRunnable implements Runnable {
@Override
public void run() {
for (int i = 1; i < 101; i++) {
System.out.println(Thread.currentThread().getName() + ":" + i);
System.out.println(Thread.currentThread().getName() + ":礼让下");
Thread.yield();
}
}
public static void main(String[] args) throws InterruptedException {
TestRunnable r = new TestRunnable();
System.out.println("线程创建前");
Thread th1 = new Thread(r,"线程1");
Thread th2 = new Thread(r,"线程2");
System.out.println("执行线程1");
th1.start();
// Thread.sleep(100);
System.out.println("执行线程2");
th2.start();
System.out.println("....");
}
}
TestMethod类:
package cn.kgc.kb09;
import java.util.TreeSet;
/**
* @Author Daniu_Ben
* @Date 2020/8/5
* @Description 常用方法
*/
public class TestMethod {
public static void main(String[] args) throws InterruptedException {
TestRunnable r = new TestRunnable();
Thread t1 = new Thread(r,"线程1:");
System.out.println("线程1创建");
System.out.println("线程2创建");
Thread t2 = new Thread(r,"线程2:");
t1.setPriority(Thread.MAX_PRIORITY);
t2.setPriority(10);
t1.start();
t2.start();
// for (int i = 0; i < 5; i++) {
// if (i == 2){
// t1.join();
// }
// System.out.println(i + 1 + "主线程中的循环");
// }
// t1.join();
// System.out.println("上面执行了join方法,主线程会等t1执行完成了再来");
}
}
课后练习
练习一:创建两个子线程,每个线程均输出20次消息数字、“你好”、线程名观察多个线程交替执行的过程
Work1类:
package cn.kgc.kb09.work;
/**
* @Author Daniu_Ben
* @Date 2020/8/5
* @Description
*/
public class Work1 implements Runnable {
@Override
public void run() {
for (int i = 0; i < 20; i++) {
System.out.println(i + ".你好,来自线程" + Thread.currentThread().getName());
}
}
public static void main(String[] args) {
Runnable r = new Work1();
Thread t = new Thread(r);
Thread t1 = new Thread(r);
t1.start();
t.start();
}
}
练习二:
每个线程代表一个人
可设置每人爬山速度
每爬完100米显示信息
爬到终点时给出相应提示
Work3_1类
package cn.kgc.kb09.work;
/**
* @Author Daniu_Ben
* @Date 2020/8/5
* @Description
*/
public class Work3_1 implements Runnable{
@Override
public void run() {
for (int i = 0; i < 10; i++) {
try {
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "爬完了100米!");
}
System.out.println(Thread.currentThread().getName() + "到达终点!");
}
}
Work3类:
package cn.kgc.kb09.work;
/**
* @Author Daniu_Ben
* @Date 2020/8/5
* @Description
*/
public class Work3 implements Runnable{
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName() + "爬完了100米!");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName() + "到达终点!");
}
public static void main(String[] args) {
Work3 w = new Work3();
Thread t1 = new Thread(w,"年轻人");
Work3_1 w1 = new Work3_1();
Thread t2 = new Thread(w1,"老年人");
t1.start();
t2.start();
}
}
练习三:显示主线程、子线程默认优先级,将主线程设置为最高优先级、子线程设置为最低优先级并显示
Work4:
package cn.kgc.kb09.work;
import java.util.concurrent.ThreadPoolExecutor;
/**
* @Author Daniu_Ben
* @Date 2020/8/5
* @Description
*/
public class Work4 implements Runnable {
@Override
public void run() {
Thread.currentThread().setPriority(1);
}
public static void main(String[] args) throws InterruptedException {
System.out.println("****显示默认优先级****");
Thread t = Thread.currentThread();
Work4 w = new Work4();
Thread t1 = new Thread(w);
System.out.println("主线程名为:" + t.getName() + ",优先级:" + t.getPriority());
System.out.println("子线程名为:" + t1.getName() + ",优先级:" + t1.getPriority());
t1.start();
t1.join();
t.setPriority(10);
System.out.println("*****修改默认优先级后*****");
System.out.println("主线程名为:" + t.getName() + ",优先级:" + t.getPriority());
System.out.println("子线程名为:" + t1.getName() + ",优先级:" + t1.getPriority());
}
}
练习4:某科室一天需看普通号50个,特需号10个
特需号看病时间是普通号的2倍,开始时普通号和特需号并行叫号,叫到特需号的概率比普通号高,当普通号叫完第10号时,要求先看完全部特需号,再看普通号,使用多线程模拟这一过程
package cn.kgc.kb09.work;
/**
* @Author Daniu_Ben
* @Date 2020/8/5
* @Description
*/
public class Work5 implements Runnable {
@Override
public void run() {
for (int i = 1; i <= 10; i++) {
System.out.println(Thread.currentThread().getName() + i + "号病人在看病!");
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
Thread t = Thread.currentThread();
t.setName("普通号:");
Work5 w = new Work5();
Thread t1 = new Thread(w,"特需号:");
t1.start();
t.setPriority(1);
t1.setPriority(10);
for (int i = 1; i <= 50; i++) {
System.out.println(t.getName() + i + "号病人在看病!");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (i == 10) {
try {
t1.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
练习五:
多人参加1000米接力跑
每人跑100米,换下个选手
每跑10米显示信息
Work6类:
package cn.kgc.kb09.work;
/**
* @Author Daniu_Ben
* @Date 2020/8/5
* @Description
*/
public class Work6 implements Runnable {
@Override
public synchronized void run() {
System.out.println(Thread.currentThread().getName() + "拿到接力棒!");
for (int i = 1; i <= 10; i++) {
System.out.println(Thread.currentThread().getName() + "跑了" + (i * 10) + "米!");
}
}
public static void main(String[] args) throws InterruptedException {
Work6 w = new Work6();
for (int i = 1; i <= 10 ; i++) {
Thread t = new Thread(w,i + "号选手");
t.start();
}
Thread.sleep(100);
System.out.println("跑完了!!");
}
}
练习六:“桃跑跑”、“张票票”、“黄牛党”共同抢10张票,限“黄牛党”只能抢一张票
Work7类:
package cn.kgc.kb09.work;
/**
* @Author Daniu_Ben
* @Date 2020/8/5
* @Description
*/
public class Work7 implements Runnable {
int num = 10;
int num2 = 0;
@Override
public void run() {
while (num > 0) {
sale();
if (Thread.currentThread().getName().equals("黄牛党"))return;
}
}
public synchronized void sale(){
num --;
num2 ++;
if (num < 0)return;
System.out.println(Thread.currentThread().getName() + "抢到了第" + num2 + "张票" + ",剩余" + num + "张票!");
}
public static void main(String[] args) {
Work7 w = new Work7();
Thread t1 = new Thread(w,"桃跑跑");
Thread t2 = new Thread(w,"张票票");
Thread t3 = new Thread(w,"黄牛党");
t2.start();
t3.start();
t1.start();
}
}