Java中实现多线程

 

进程:每个进程都有独立的代码和数据空间(进程上下文),进程间的切换会有较大的开销,一个进程包含1--n个线程。

线程:同一类线程共享代码和数据空间,每个线程有独立的运行栈和程序计数器(PC),线程切换开销小。

线程和进程一样分为五个阶段:创建、就绪、运行、阻塞、终止。

多进程是指操作系统能同时运行多个任务(程序)。

多线程是指在同一程序中有多个顺序流在执行。

在java中要想实现多线程,有两种手段一种是继承Thread类,另外一种是实现Runable接口。

实际上所有的多线程代码执行顺序都是不确定的,每次执行的结果都是随机的。

 

继承Thread类:一个类只要继承了Thread类同时覆写了本类中的run()方法就可以实现多线程操作了,但是一个类只能继承一个父类,这是此方法的局限。

但是在使用Runnable定义的子类中没有start()方法,只有Thread类中才有。Thread类中有一个构造方法:public Thread(Runnable targer)此构造方法接受Runnable的子类实例,也就是说可以通过Thread类来启动Runnable实现的多线程(start()可以协调系统的资源)。因为是同一个runnable对象,所以多个Thread对象传入同一个Runnable对象可以实现资源共享。

start()方法的调用后并不是立即执行多线程代码,而是使得该线程变为可运行态(Runnable),什么时候运行是由操作系统决定的。

从程序运行的结果可以发现,多线程程序是乱序执行。因此,只有乱序执行的代码才有必要设计为多线程。

Thread.sleep()方法调用目的是不让当前线程独自霸占该进程所获取的CPU资源,以留出一定时间给其他线程执行的机会。

方式1:继承Thread类
步骤
1、自定义类MyThread继承Thread类。
2、MyThread类里面重写run()
3、创建对象
4、启动线程

方式2:实现Runnable接口

步骤:

1、自定义类MyRunnable实现Runnable接口
2、重写run()方法
3、创建MyRunnable类的对象
4、创建Thread类的对象,并把C步骤的对象作为构造参数传递

lass MyThread extends Thread {
    private int ticket = 5;
 
    public MyThread(String name) {
        super(name);
    }
 
    public void run() {
        for (int i = 0; i < 5; i++) {
            sale();
        }
    }
 
    //使用同步方法
    public void sale() {
        if (this.ticket > 0) {
            System.out.println(Thread.currentThread().getName()
                    + "卖票:1张 " + this.ticket--);
        }
    }
 
    public static void main(String[] args) {

        Thread thread1 = new MyThread("售票口一");
        Thread thread2 = new MyThread("售票口二");
        Thread thread3 = new MyThread("售票口三");
        thread1.start();
        thread2.start();
        thread3.start();
    }
}

执行结果如下:

售票口一卖票: 5
售票口一卖票: 4
售票口一卖票: 3
售票口一卖票: 2
售票口一卖票: 1
售票口三卖票: 5
售票口三卖票: 4
售票口三卖票: 3
售票口三卖票: 2
售票口三卖票: 1
售票口二卖票: 5
售票口二卖票: 4
售票口二卖票: 3
售票口二卖票: 2
售票口二卖票: 1

 每个线程都有5张票。并没有资源共享。

class mythread implements Runnable{
		
	private int ticketnum=100;
	public void run() {
		while(ticketnum>0) {
				if(ticketnum>0) {
					System.out.println(Thread.currentThread().getName()+"售出第"+ticketnum--+"张");
				}
		}
	}	
}
public class Job01{
	public static void main(String[] args) {
		mythread temp=new mythread();
		Thread t1= new Thread(temp,"窗口A");//同一个temp,如果在Thread中就不行,会报错
		Thread t2= new Thread(temp,"窗口B");
		Thread t3= new Thread(temp,"窗口C");
		Thread t4 = new Thread(temp,"窗口D");
		t1.start();
		t2.start();
		t3.start();
		t4.start();
	}
}

 

输出:(一种可能)

窗口A售出第100张
窗口A售出第99张
窗口A售出第98张
窗口A售出第97张
窗口A售出第96张
窗口A售出第95张
窗口A售出第94张
窗口A售出第93张
窗口A售出第92张
窗口A售出第91张
窗口A售出第90张
窗口A售出第89张
窗口A售出第88张
窗口A售出第87张
窗口A售出第86张
窗口A售出第85张
窗口C售出第83张
窗口C售出第82张
窗口C售出第81张
窗口C售出第80张
窗口C售出第79张
窗口C售出第78张
窗口C售出第77张
窗口C售出第76张
窗口C售出第75张
窗口C售出第74张
窗口C售出第73张
窗口C售出第72张
窗口C售出第71张
窗口C售出第70张
窗口C售出第69张
窗口C售出第68张
窗口C售出第67张
窗口C售出第66张
窗口C售出第65张
窗口C售出第64张
窗口C售出第63张
窗口C售出第62张
窗口C售出第60张
窗口C售出第59张
窗口C售出第58张
窗口C售出第57张
窗口C售出第56张
窗口C售出第55张
窗口C售出第54张
窗口C售出第52张
窗口C售出第51张
窗口C售出第50张
窗口C售出第49张
窗口C售出第48张
窗口C售出第47张
窗口C售出第46张
窗口C售出第45张
窗口C售出第44张
窗口C售出第43张
窗口C售出第42张
窗口C售出第41张
窗口C售出第40张
窗口C售出第39张
窗口C售出第38张
窗口C售出第37张
窗口C售出第36张
窗口C售出第35张
窗口C售出第34张
窗口C售出第33张
窗口C售出第32张
窗口C售出第31张
窗口C售出第30张
窗口C售出第29张
窗口C售出第28张
窗口C售出第27张
窗口C售出第26张
窗口C售出第25张
窗口C售出第24张
窗口C售出第23张
窗口C售出第22张
窗口C售出第21张
窗口C售出第20张
窗口C售出第19张
窗口C售出第18张
窗口C售出第17张
窗口C售出第16张
窗口B售出第84张
窗口C售出第15张
窗口D售出第53张
窗口A售出第61张
窗口D售出第12张
窗口C售出第13张
窗口B售出第14张
窗口C售出第9张
窗口D售出第10张
窗口A售出第11张
窗口D售出第6张
窗口C售出第7张
窗口C售出第3张
窗口B售出第8张
窗口C售出第2张
窗口D售出第4张
窗口A售出第5张
窗口B售出第1张

(我为什么要设置成100张票 -_-|||)
避免资源抢占使用synchronized以下改进

class mythread implements Runnable{
	 private int num=100;
	public void run(){	
		while(num>0){
			synchronized(this) {//避免抢占资源(例:窗口A,B售出了第44张票)
			if(num>0)
			System.out.println(Thread.currentThread().getName()+"售出第 "+num--+"张票");
			//让当前线程睡眠一段时间,利于其他线程执行
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				// TODO 自动生成的 catch 块
				e.printStackTrace();
			}
		  }
	  }
   }
}
public class Job01{
	public static void main(String[] args) {
		mythread temp=new mythread();
		Thread t1=new Thread(temp,"线程A");
		Thread t2=new Thread(temp,"线程B");
		Thread t3=new Thread(temp,"线程C");
		//设置了优先级
		t1.setPriority(10);
		t2.setPriority(1);
		t3.setPriority(1);
		t1.start();
		t2.start();
		t3.start();
	}
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值