黑马程序员————java基础之线程

 --------Java培训、Android培训、iOS培训、.Net培训、期待与您交流!

一.进程线程、多进程的概念

进程:就是正在进行的程序

线程:进程中程序负责执行的控制单元

多线程:一个进程中有多个执行路径
多线程的好处:解决了多部分代码同时运行的问题。
多线程的弊端:线程太多,会导致效率的降低。
其实,多个应用程序同时执行都是CPU在做着快速的切换完成的。 这个切换是随机的。 CPU的切换是需要花费时间的,从而导致了效率的降低。

注:
一个进程中至少要有一个线程。开启多个线程是为了同时运行多部分代码,每一个线程都有自己运行的内容,这个内容可以称为线程要执行的任务。
创建线程的两种方式
(1)继承Thread类
步骤:
(1)定义一个类继承Thread类
(2)覆盖Thread类中的run方法
    run方法中定义的是线程要运行的任务代码,开启线程是为了运行指定代码,所以只有继承Thread类,并复写run方法,将运行的代码定义在run方法中即可。
(3)直接创建Thread的子类对象创建线程
(4)调用start方法开启线程并调用线程方法

简单代码如下:

class Demo1 extends Thread //定义一个类继承线程类Thread
{
        private String name;//私有一个字符串引用 name
        Demo1(String name)//构造函数对Demo1进行初始化并具有属性name
        {
                super(name);
       //this.name=name;
         }

        public void run()//定义一个run函数来覆盖Thread
        {
                for(int x=0;x<10;x++)
                {
                        for(int y=-100000;y<890980;y++){}
                        System.out.println(name+"....x="+x+"....name="+Thread.currentThread().getName());//输出里面调用了getName方法
                }
        }
}
class DemoThread
{
   public static void main(String[] args) 
{   Demo1 s1=new Demo1("小皓");//创建Thread子类对象
     Demo1 s2=new Demo1("小静");
         s1.start();//调用strat方法开启线程
         s2.start();
         for(int  w=0;w<10;w++)
           {

              System.out.println("小胖子....w="+w+"....name="+Thread.currentThread().getName());
           }
                
        }
}
运行结果:小胖子....w=0....name=main
小胖子....w=1....name=main
小胖子....w=2....name=main
null....x=0....name=小静
null....x=0....name=小皓
null....x=1....name=小静
小胖子....w=3....name=main
null....x=2....name=小静
null....x=1....name=小皓
null....x=3....name=小静
null....x=4....name=小静
null....x=5....name=小静
null....x=6....name=小静
null....x=7....name=小静
null....x=8....name=小静
null....x=9....name=小静
小胖子....w=4....name=main
小胖子....w=5....name=main
小胖子....w=6....name=main
小胖子....w=7....name=main
小胖子....w=8....name=main
小胖子....w=9....name=main
null....x=2....name=小皓
null....x=3....name=小皓
null....x=4....name=小皓
null....x=5....name=小皓
null....x=6....name=小皓
null....x=7....name=小皓
null....x=8....name=小皓
null....x=9....name=小皓
小结:
(1)线程运行有随机性,抢占cpu
(2)整个类去继承Thread只是为了覆盖run方法,有点浪费,并且java不支持多继承势必会造成局限性。
(3)如果多线程执行的是一个有总数的项目 比如多线程进行卖票,就会new出多个对象,每个对象都是独立的这种方法就不行了。

创建线程方式二:实现Runnable接口

步骤:(1) 定义runnable接口
(2) 覆盖接口中的run方法将线程的任务代码封装到run方法中
(3)通过Thread类创建线程对象,并将Runnable接口的子类对象作为Thread类的构造函数的参数进行传递
(4)调用线程对象的start方法开启线程。
package test;
class Demo2 implements Runnable//实现runnable接口 
{
	public void run(){  //覆盖run方法
		show();//调用show方法
	}
private void show() {
		// TODO Auto-generated method stub
		for(int i=0;i<3;i++){
			System.out.println(Thread.currentThread().getName() + "..." + i);
		}
	}
	}
public class Demo1{
	public static void main(String[] args) {
		// TODO Auto-generated method stub
Demo2 d= new Demo2();//创建Demo2对象
Thread t1 = new Thread(d);//创建Thread类并将并将Runnable接口的子类对象做为参数传递
Thread t2 =new Thread(d);
t1.start();//开启线程
t2.start();
	}

}
运行结果如下:
Thread-0...0
Thread-0...1
Thread-0...2
Thread-1...0
Thread-1...1
Thread-1...2
实现Runnable接口的好处:
1. 将线程的任务从线程的子类中分离出来,进行了单独的封装,按照面向对象的思想将任务封装成对象。
2. 避免了Java单继承的局限性。 所以,创建线程的第二种方式较为常用。
线程安全问题
根据卖票例子可以发现 Thread-0通过了if判断后,在执行到“ num--” 语句之前,num此时仍等于1。CPU切换到Thread-1、 Thread-2、 Thread-3之后,这些线程依然可以通过if判断,从而执行“ num--” 的操作,因而出现了0、 -1、 -2的情况。
线程安全问题产生的原因:
1. 多个线程在操作共享的数据。
2. 操作共享数据的线程代码有多条。
当一个线程在执行操作共享数据的多条代码过程中,其他线程参与了运算,就会导致线程安全问题的产生。

线程安全问题的解决方案
(1)在java中,用同步代码块就可以解决这个问题。
同步代码块的格式:
synchronized(对象){
需要被同步的代码;
} 同步的好处:解决了线程的安全问题。
同步的弊端:当线程相当多时,因为每个线程都会去判断同步上的锁,这是很耗费资源的,无形中会降低程序的运行效率。
同步的前提:必须有多个线程并使用同一个锁。
(2)
格式:在函数上加上synchronized修饰符即可。
注:同步的目的就是加上锁,谁符合条件就进去执行任何锁上别的线程就进不来了 等到运行结束后再打开锁让这些线程再去抢cup。

线程间通信涉及的方法
多个线程在处理统一资源,但是任务却不同,这时候就需要线程间通信。
等待/唤醒机制涉及的方法:
1. wait():让线程处于冻结状态,被wait的线程会被存储到线程池中。
2. notify():唤醒线程池中的一个线程(任何一个都有可能)。
3. notifyAll():唤醒线程池中的所有线程。
注:
1、这些方法都必须定义在同步中,因为这些方法是用于操作线程状态的方法。
2、必须要明确到底操作的是哪个锁上的线程!
3、wait和sleep区别?
1)wait可以指定时间也可以不指定。sleep必须指定时间。
2)在同步中时,对CPU的执行权和锁的处理不同。
wait:释放执行权,释放锁。
sleep:释放执行权,不释放锁


















  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值