Java基础---线程(一)

Java基础---线程

 

这里写下关于java基础的一些知识,便于自己的复习和分享给大家共同学习! 有指教的地方请留言,共同学习进步!

 

一, 什么是线程?线程的基础概念

   1,线程是一个程序内部的顺序控制流,可以理解为是一个程序里面不同的执行路径

   2,每个分支都叫做一个线程,我们程序所写的main()叫做主分支,也叫主线程。

   3,可以通过创建Thread的实例来创建新的线程

   4,每个线程都是通过某个特定的Thread对象对应的run()方法来完成操作的,方法run()成为线程体,通过调用Thread类的start()方法来启动一个线程。

二,什么是进程?

       进程可以看成是一个程序执行的实例,程序一旦允许就是一个进程,每个进程都拥有一个独立地址空间。

       一个进程可以拥有多个线程,每个线程使用其所属的进程的栈空间。

三,线程和进程的区别?

        1,每个进程都有独立的代码空间和数据,进程间的切换会有较大的开销

        2,线程可以看成轻量级的进程,同一类线程共享代码和数据空间,线程切换开销较小。

        3,多进程:操作系统中可以同时运行多个程序。

        4,线程没有独立的内存空间

         5,线程是寄生在进程中。

四,多线程:

         多线程:一个进程中不只有一个线程。

        为什么要使用多线程?

       1,Java语言内置了多线程功能支持,简化了java多线程的编程。

       2,进程之间不能共享数据,线程可以。

       3,系统创建进行需要为该进程分配系统资源,创建线程代价较小

       4,为了更有效的利用CPU资源,如果只有一个线程,则第二个任务必须等到第一个任务结束后才能进行。如果使用多线程,就可以在主线程执行任务时,也可以执行其他任务,不需要等待。

这里说下CPU的工作原理:

          CPU 执行速度非常快,一秒钟可以算几亿次,所以CPU吧自己的时间分成了一个一个的时间片,这个时间片这个程序执行,第二个时间片另一个程序执行,以此类推。虽然有很多线程,但是一样可以在很短的时间之内把它们执行,因CPU执行的速度之快,所以我们看起来好像同一时间执行一样,其实是在一个时间点上,CPU 只有一个线程在运行。

 

五,启动线程和创建线程

二种主要方式:

      1,继承Thread类,重写run函数,调用start()方法。

           定义一个Thread的子类,继续Thread类,重写run方法, 将代码存储在run方法,让线程运行

public class ThreadDemo2 {

	public static void main(String[] args) {

		// 创建两个线程
		ThreadDemo td1 = new ThreadDemo("zzzzzzzz");
		ThreadDemo td2 = new ThreadDemo("sssss");
		// 如果使用.run();也会执行,但会单线程方式执行。
		td1.start();
		td2.start();
		// 主线程
		for (int i = 0; i <6; i++) {
			System.out.println("主线程" + ":run" + i);
		}
	}
}

// 继承Thread类
class ThreadDemo extends Thread {

	// 设置线程名称
	ThreadDemo(String name) {
		super(name);
	}

	// 重写run方法。
	@Override
	public void run() {
		for (int i = 0; i < 8; i++) {
			System.out.println(this.getName() + ":run" + i);
		}
	}
}

   2,实现Runnable接口:

      定义一个类实现Runnable接口,覆盖Runnable接口中的Run方法,将要执行的代码放在run方法中,

通过Thread类创建线程对象,然后将实现Runnable接口的子类对象       

public class TestRunn {

	public static void main(String args[]){
        Runn1 r1 = new Runn1();//这里new了一个线程类的对象出来
        //r1.run();//这个称为方法调用,方法调用的执行是等run()方法执行完之后才会继续执行main()方法
        Thread t = new Thread(r1);//要启动一个新的线程就必须new一个Thread对象出来
        //这里使用的是Thread(Runnable target) 构造方法
        t.start();//启动新的线程,新线程执行的是run()方法,新线程与主线程会一起并行执行
        for(int i=0;i<10;i++){
            System.out.println("maintheod:"+i);
        }
    }
}
/*定义一个类用来实现Runnable接口,实现Runnable接口就表示这个类是一个线程类*/
class Runn1 implements Runnable{
    public void run(){
        for(int i=0;i<10;i++){
            System.out.println("Runn1:"+i);
        }
    }
}

六,Sleep/ join /yield方法

Sleep方法: 

    可以调用Thread的静态方法,使得当前线程休眠,单位为毫秒,由于是静态方法,可以直接用类名调用

 Join方法:

     线程实例的方法join()方法可以使得一个线程在另一个线程结束后再执行。如果join()方法在一个线程实例上调用,当前运行着的线程将阻塞直到这个线程实例完成了执行。

 Yield方法:

      让出CPU使用权 ,给其他线程执行的机会

Sleep()  Demo:


public class Thread1 {
	public static void main(String[] args) {
		Runner1 r1 = new Runner1();		
		Thread t = new Thread(r1);		
		t.start();
		for (int i = 0; i < 5; i++) {
			System.out.println("main thread :"+i);
		}		
	}
}
 
class Runner1 implements Runnable{
	@Override
	public void run() {		
        try {
			Thread.sleep(5000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
        for (int i = 0; i < 5; i++) {
        	System.out.println("Runner1 : " + i);
        }
	}	
}

main thread:4 和Runner1:0 之间睡了5秒

     Join()  Demo:

   

public class TestThread4 {
    public static void main(String args[]) {
        MyThread2 thread2 = new MyThread2("mythread");
        // 创建一个新线程对象,线程对象命名为mythread
        thread2.start();// 启动线程
        try {
            thread2.join();// 调用join()方法合并线程,将子线程mythread合并到主线程里面
            // 合并线程后,程序的执行的过程就相当于是方法的调用的执行过程
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        for (int i = 0; i <= 5; i++) {
            System.out.println("I am main Thread");
        }
    }
}

class MyThread2 extends Thread {
    MyThread2(String s) {
        super(s);
        /*
         * 使用super关键字调用父类的构造方法 
         * 父类Thread的其中一个构造方法:“public Thread(String name)” 
         * 通过这样的构造方法可以给新开辟的线程命名,便于管理线程
         */
    }

    public void run() {
        for (int i = 1; i <= 5; i++) {
            System.out.println("I am a\t" + getName());
            // 使用父类Thread里面定义的
            //public final String getName(),Returns this thread's name.
            try {
                sleep(1000);// 让子线程每执行一次就睡眠1秒钟
            } catch (InterruptedException e) {
                return;
            }
        }
    }
}

结果如下,每隔一秒钟输出一个i am a mythread;

Yield Demo :

public class TestThread6 {
    public static void main(String args[]) {
        MyThread4 t1 = new MyThread4("t1");
        /* 同时开辟了两条子线程t1和t2,t1和t2执行的都是run()方法 */
        /* 这个程序的执行过程中总共有3个线程在并行执行,分别为子线程t1和t2以及主线程 */
        MyThread4 t2 = new MyThread4("t2");
        t1.start();// 启动线程t1
        t2.start();// 启动线程t2
        for (int i = 0; i <= 5; i++) {
            System.out.println("I am main Thread");
        }
    }
}

class MyThread4 extends Thread {
    MyThread4(String s) {
        super(s);
    }

    public void run() {
        for (int i = 1; i <= 5; i++) {
            System.out.println(getName() + ":" + i);
            if (i % 2 == 0) {
                yield();// 当执行到i能被2整除时当前执行的线程就让出来让另一个在执行run()方法的线程来优先执行
                /*
                 * 运行时候观察到:
                 * 线程t1执行到(i%2==0)次时就会让出线程让t2线程来优先执行 
                 * 而线程t2执行到(i%2==0)次时也会让出线程给t1线程优先执行
                 */
            }
        }
    }
}

运行结果为:

欢迎指教~ 后续继续。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值