1 .给线程赋名字的两种方式:
通过调用父类的构造方法也可以给 线程赋值名字,
也可以this调用set方法
2 .自己写的类继承Thread的时候要注意,Thread 类中 setName 和 getName 是final修饰的只能被继承 ,不能被重写.继承类中name属性不用写.
3 .
package com.qf.demo4;
public class Test3 {
public static void main(String[] args) {
MyThread2 thread2 = new MyThread2("二狗");
MyThread2 thread3 = new MyThread2("小香菇");
thread2.start();
thread3.start();
}
}
class MyThread2 extends Thread{
public MyThread2(String name) {
super(name);// 通过 调用父类的构造方法也可以给 线程赋值名字
//this.setName(name);// 可以给 线程赋值名字
}
/*Thread 类中 setName 和 getName 是final修饰的只能被继承 不能被重写
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}*/
@Override
public void run() {
//Thread.currentThread().setName("abcde");
System.out.println(Thread.currentThread().getName());
}
}
4 . 当自定义类继承Thread类时,可以自己在继承类中加别的属性,name不用写,直接可以用supur(name)进行名字的赋值
5 .还要注意在主方法中,子类对象调用的是start,会开辟新的栈空间,创建多个线程,会自动执行子类中重写的run(),但是如果此对象直接在main方法中直接调用run()的话,不会产生新的线程.
package com.qf.demo4;
/**
* 建造地标性建筑 需要多个工人 使用多线程实现
*
* 50次
*/
public class Test4 {
public static void main(String[] args) {
MyThread3 thread3 = new MyThread3("皮皮虾", "开挖掘机");
MyThread3 thread4 = new MyThread3("达康书记", "搬砖");
MyThread3 thread5 = new MyThread3("静静的学习", "抗炸药包");
// 这是 当调用start 会开辟 新的栈空间, 多个线程
thread3.start();
thread4.start();
thread5.start();
// 简单的方法调用, 并不会产生新的 线程
// thread3.run();
// thread4.run();
// thread5.run();
}
}
class MyThread3 extends Thread{
private String work;
public MyThread3(String name,String work){
super(name);
this.work = work;
}
@Override
public void run() {
for (int i = 0; i < 50; i++) {
System.out.println(Thread.currentThread().getName()+"工作是"+work+",已```````
工作了"+i+"个小时");
}
}
}
6 .火车站
* 卖票的
* 一共四个窗口 , 每个窗口卖100张票
package com.qf.demo4;
/**
* 火车站
* 卖票的
* 一共四个窗口 , 每个窗口卖100张票
*/
public class Test5 {
public static void main(String[] args) {
Window window = new Window("窗口一");
Window window2 = new Window("窗口二");
Window window3 = new Window("窗口三");
Window window4 = new Window("窗口四");
window.start();
window2.start();
window3.start();
window4.start();
}
}
class Window extends Thread{
public Window(String name) {
super(name);
}
@Override
public void run() {
for (int i = 1; i <=100; i++) {
System.out.println(Thread.currentThread().getName()+"卖了"+(i)+"张票,还剩下"+(100-i)+"张票");
}
}
}
7 . 关于主线程和子线程:
如果主线程执行过程中,创建了子线程,则主线程和子线程会争抢cpu资源
package com.qf.demo4;
/**
* 系统默认的这个线程 名字是 main 可以叫做main线程 ,主线程
*
* 自己单独创建的线程 子线程, 工作线程
*
*
* 通常情况
* 把耗时操作 放到子线程中执行
*
*
*
*/
public class Test2 {
public static void main(String[] args) {
//主线程 下载大视频
// for (int i = 0; i < args.length; i++) {
//
// }
//
// 创建线程对象 , 并没有让线程启动起来
MyThread thread = new MyThread();
MyThread thread2 = new MyThread();
// 启动线程
thread.start();
thread2.start();
for (int i = 0; i < 20; i++) {
System.out.println(Thread.currentThread().getName()+"haha"+i);
}
}
}
class MyThread extends Thread{
@Override
public void run() {
for (int i = 0; i < 20; i++) {
// 得到当前执行的 线程的名字
System.out.println(Thread.currentThread().getName()+"自己创建的线程"+i);
}
}
}
上面代码中,thread子线程和thread2子线程和主线程争抢资源,主方法中主线程的for和两个子类的的for会争抢执行,但是如果main中的代码把for放在两个子线程前面,则先回执行完主线程的for,再去执行两个子线程的for,因为在主线程执行for时,子线程还没有别启动
public static void main(String[] args) {
//主线程 下载大视频
// for (int i = 0; i < args.length; i++) {
//
// }
//
// 创建线程对象 , 并没有让线程启动起来
MyThread thread = new MyThread();
MyThread thread2 = new MyThread();
for (int i = 0; i < 20; i++) {
System.out.println(Thread.currentThread().getName()+"haha"+i);
}
// 启动线程
thread.start();
thread2.start();
}
}