Java基础学习day16
程序时一段静态代码
进程是程序的一次执行过程,正在执行的程序
线程是一个程序内部的一条执行路径
多线程的创建
- 创建一个继承Thread的子类
- 重写Tread父类的run方法
- 创建Thread的子类对象
- 通过对象调用start()方法
- 启动当前线程
- 调用当前线性的run方法
public class ThreadTest {
public static void main(String[] args) {
MyThread myThread = new MyThread();
myThread.start();
for (int i = 1; i < 100; i++) {
if (i%2==0){
System.out.println(i+"*");
}
}
}
}
class MyThread extends Thread {
@Override
public void run() {
for (int i = 1; i < 100; i++) {
if (i % 2 == 0) {
System.out.println(i);
}
}
}
}
问题一:我们不能通过子类对象直接调用run方法来启动线程
因为我们只是执行了类的方法,start则是创建一个线程,在本线程中调用run()方法
问题二:再启动一个线程,遍历100以内的偶数。不可以还让已经start()的线程去执行。
不行的,start只会创建一次线程,如果再次执行将会报线程不合法异常
处理办法重新new一个子类对象,调用父类的start方法
练习
创建两个线程一个遍历100以内偶数,一个遍历100以内奇数(匿名内部类方式)
public class ThreadDemo {
public static void main(String[] args) {
MyThread myThread = new MyThread();
myThread.start();
new Thread(){
@Override
public void run() {
for (int i = 0; i < 100; i++) {
if(i%2!=0){
System.out.println(Thread.currentThread().getName()+"---"+i);
}
}
}
}.start();
}
}
class MyThread extends Thread{
@Override
public void run() {
for (int i = 0; i < 100; i++) {
if(i%2==0){
System.out.println(Thread.currentThread().getName()+"***"+i);
}
}
}
}
测试Thread中常用方法
1.start():启动当前线程;调用当前线程run ()
2.run():通常需要重写Thread中的此方法,将创建线程需要的操作写在此方法体中
3.yield():释放当前cpu的执行权,不意味着一定不执行当前线程,可能又会重新分配给当前线程
4.join():在线程a中调用线程b的join()方法,此时a线程将变为阻塞状态,知道线程b完全执行完以后,线程a才结束阻塞状态
5.stop():已过时,不推荐使用,强制结束当前线程
6.sleep(long millitime):让当前线程睡眠指定的millitime毫秒。指定的millitime毫秒内,当前线程为阻塞状态
7.currentThread():静态方法,返回执行当前代码的线程
8.getName():获取线程名字
9.setName():设置线程名字(也可以通过构造器设置名字)
10.isAlive():判断当前线程是否存活
线程的优先级:
MAX PRIORITY:10
MIN PRIORITY:1
NORM PRIORITY:5–>默认优先级
2.如何获取和设置当前线程的优先级:
getpriority():获取线程的优先级
setpriority(int p):设置线程的优先级
说明:高优先级的线程要枪占低优先级线程CPU的执行权。但是只是从率上讲,高优先级的线程高概率的情况下
被执行。并不意味着只有当高优先级的线程执行完以后,低优先级的线程才执行。
例子:三个窗口共同卖100张票
public class MyThread extends Thread {
private static int total = 100;
@Override
public void run() {
while (true){
if(total<=0){
break;
}else{
System.out.println(getName()+"***"+total--);
}
}
}
public static void main(String[] args) {
MyThread myThread = new MyThread();
MyThread myThread1 = new MyThread();
MyThread myThread2 = new MyThread();
myThread.start();
myThread1.start();
myThread2.start();
}
}
多线程的创建(二)
1.创建一个实现了Runnable接口的类
2.实现类去实现Runnable中的抽象方法run()
3.创建实现类对象
4.将此对象作为参数传递到Thread类的构造器中,创建Thread类对象
5.通过Thread类的对象调用start()方法
public class ThreadTest implements Runnable{
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println(Thread.currentThread().getName()+"***"+i);
}
}
public static void main(String[] args) {
ThreadTest threadTest = new ThreadTest();
Thread thread = new Thread(threadTest);
thread.start();
Thread thread1 = new Thread(threadTest);
thread1.start();
}
}
例子:三个窗口共同卖100张票
因为是将创建好的类放入Thread的构造器中,所以类只调用一次,就是100张票
public class MyThread1 implements Runnable{
private int total = 100;
@Override
public void run() {
while (true){
if (total>0){
System.out.println(Thread.currentThread().getName()+"***"+total--);
}else {
break;
}
}
}
public static void main(String[] args) {
MyThread1 myThread1 = new MyThread1();
Thread thread = new Thread(myThread1);
thread.setName("窗口1");
thread.start();
Thread thread1 = new Thread(myThread1);
thread1.setName("窗口2");
thread1.start();
Thread thread2 = new Thread(myThread1);
thread2.setName("窗口3");
thread2.start();
}
}
比较创建线程的两种方式
推荐使用继承Runnable接口的方式
原因:1.实现的当时没有类的单继承的局限性
2.实现的方式更适合来处理多个线程又共享数据的情况
联系:public class Thread implements Runnable
相同的:两种方式都要重新run方法,将线程要执行的逻辑声明在run方法中