1.多线程编程方式1:通过继承Thread
package cn.sk.thread;
/**本类用于多线程编程方式一 extends Thread*/
public class Thread1{
public static void main(String[] args) {
/**如果只是调用run(),那么会执行完一个线程,再执行另一个线程
* 不会有多线程抢占资源的效果,所以,我们真的能通过run()来执行多线程任务吗?
* run()与start()本质区别,run()只能当做一个顺序执行的单线程普通方法
* 并没有多线程抢占的效果,所以如果想以多线程的效果干活必须调用start()方法才能
* 真正的启动线程*/
//5.创建自定义线程对象
MyThread t = new MyThread();
//6.模拟多线程,需要至少启动两个线程,如果只启动一个线程,是单线程
MyThread t2 = new MyThread();
MyThread t3 = new MyThread("旺财");
MyThread t4 = new MyThread("小白");
MyThread t5 = new MyThread("小黄");
//t.run();
//t2.run();
/**当我们调用start()方法启动线程时,虚拟机会自动调用run()的业务*/
t2.start();/**对应的是就绪状态*/
t.start();
t3.start();
t4.start();
t5.start();
/**测试结果:
* 线程有随机性,执行结果不可控,因为这是CPU在调度,我们无法控制
* */
}
}
//1.自定义多线程类
class MyThread extends Thread{
public MyThread() {
}
public MyThread(String name) {
//调用父类的含参构造,将线程名传给Thread类的含参构造方法,给线程起名字
super(name);
}
//2.1线程中的业务必须写在run方法里--规定!!
/**父类的实现是我们不需要的,我们有自己的业务*/
/* @Override
public void run() {
if (target != null) {
target.run();
}
}*/
@Override
public void run() {
/**super表示父类对象的引用,也就是使用的是Thread类本身的业务,不用*/
//super.run();
//4.写业务:输出10次当前正在执行的线程名称
for (int i = 1; i < 11; i++) {
/**getName()可以获取正在执行任务的线程名称,使用的是继承过来的方法*/
System.out.println(i+"="+getName());
}
}
}
2.多线程编程方式2:通过实现接口Runnable
package cn.sk.thread;
/**本类用于实现多线程编程方式二 implemnets Runnable*/
public class Thread2 {
public static void main(String[] args) {
//4.创建线程对象
MyRunnable target = new MyRunnable();
//5.2问题:怎么把接口的实现类与Thread关联?
Thread t = new Thread(target);//线程对象,具体去干活
Thread t1 = new Thread(target);
Thread t2 = new Thread(target);
Thread t3 = new Thread(target,"小绿");
//5.1如何以多线程的方式启动线程?
t.start();
t1.start();
t2.start();
t3.start();
}
}
//1.自定义多线程类
class MyRunnable implements Runnable{
//2.把业务放在run()中,重写了Runnable接口里的run()
@Override
public void run() {
//3.写业务,打印当前正在执行的线程的名字,10次
for (int i = 1; i < 11; i++) {
//问题:Runnable接口中,没有提供多余的方法,唯独只有一个run()
//Thread.currentThread()
//获取当前正在执行业务的线程对象,这个方法是静态的,可以被类名直接调用
System.out.println(Thread.currentThread().getName());
}
}
}