关于java多线程实验小结_java 多线程 小结

本文介绍了Java中实现多线程的两种方式:继承Thread类和实现Runnable接口,并通过示例代码展示了它们的区别。着重强调了Runnable在数据共享上的优势。还提到了线程常用函数如join(), interrupt(), setDaemon(true)的作用,以及synchronized关键字和wait(), notify(), notifyAll()在生产者-消费者问题中的应用。" 125107885,11834852,HTML5与JavaScript实现小矮人行走动画,"['HTML', 'JavaScript', '前端开发', 'canvas']
摘要由CSDN通过智能技术生成

java有点不同,实现多线程有两种方式:继承类Thread, 和 实现接口Runnable。

thread类有一个run函数,它是线程的入口,当启动一个新线程是,就从这个函数开始执行;

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.pngView Code

public class ThreadTest extendsThread{public voidrun()

{for (int i=0;i<5;i++)

{try{

Thread.sleep(1000);

}catch(InterruptedException e) {//TODO Auto-generated catch block

e.printStackTrace();

}

System.out.println(Thread.currentThread().getName()+" "+i);

}

}public static voidmain(String[] args)

{

ThreadTest test1= newThreadTest();

ThreadTest test2= newThreadTest();

test1.start();

test2.start();

}

}

注意线程是调用start()来开始的。

Runnable有一点点不同,实现这个类的时候和Thread一样,但是创建线程的时候还是放入一个Thread中创建:

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.pngView Code

public class RunnableTest implementsRunnable

{private intcnt;public RunnableTest(intn)

{super();

cnt=n;

}public voidrun()

{for (int i=0;i<5;i++)

{try{

Thread.sleep(1000);

}catch(InterruptedException e) {//TODO Auto-generated catch block

e.printStackTrace();

}

System.out.println(Thread.currentThread().getName()+" "+i+" "+--cnt);

}

}public static voidmain(String[] args)

{

RunnableTest t= new RunnableTest(10);

Thread ta= newThread(t);

Thread tb= newThread(t);

ta.start();

tb.start();

}

}

Thread和Runnable基本用法都是差不多的,但是从上面的例子可以看出,Runnable比较方便进程间数据的共享(公用了一个cnt计量单位),所以一样都使用Runnable。

线程常用的几个函数:

join():  强制等待线程执行完毕。 例如如果在主线程里面加一句ta.join(),那么主线程会一直等待ta执行返回才接着执行后面的代码。但是在join之前已经创建的其他线程,则不会受影响,继续执行。

interrupt(): 挺有意思的一个函数,如果线程在执行sleep()函数 ,则打断它(以让sleep()函数抛出一个异常的方式中断),执行后面的语句。

setDaemon(true):设置为守护进程。守护进程的优先级是最低的,如果一个程序只剩下守护进程,那么它就中断所有守护进程而退出。 最常见的情况是,如果创建的全部是守护进程,那么当主函数main执行完毕后,就立刻终止所有线程而退出。

synchronized同步符号用法: 保证同一时刻,某段代码只有一个线程在执行。

wait()和notify(),notifyAll():让线程等待/唤醒。这两个函数比较奇怪,目前我不是很熟练,要配合synchronized符号使用,请看下面这个生产者-消费者例子(网上直接贴来的,写的挺好的):

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.pngView Code

public classtt {public static voidmain(String[] args) {

Storage s= newStorage();

Producer p= newProducer(s);

Consumer c= newConsumer(s);

Thread tp= newThread(p);

Thread tc= newThread(c);

tp.start();

tc.start();

}

}class Consumer implements Runnable {//消费者

Storage s = null;publicConsumer(Storage s){this.s =s;

}public voidrun() {for(int i=0; i<20; i++){

Product p= s.pop();//取出产品

try{

Thread.sleep((int)(Math.random()*1500));

}catch(InterruptedException e) {

e.printStackTrace();

}

}

}

}class Producer implements Runnable {//生产者

Storage s = null;publicProducer(Storage s){this.s =s;

}public voidrun() {for(int i=0; i<20; i++){

Product p= newProduct(i);

s.push(p);//放入产品//System.out.println("生产者放入:" + p);

try{

Thread.sleep((int)(Math.random()*1500));

}catch(InterruptedException e) {

e.printStackTrace();

}

}

}

}classProduct {intid;public Product(intid){this.id =id;

}public String toString(){//重写toString方法

return "产品:"+this.id;

}

}classStorage {int index = 0;

Product[] products= new Product[5];public synchronized void push(Product p){//放入

while(index==this.products.length){try{this.wait();

}catch(InterruptedException e) {

e.printStackTrace();

}

}this.products[index] =p;

System.out.println("生产者放入"+index+"位置:" +p);

index++;this.notifyAll();

}public synchronized Product pop(){//取出

while(this.index==0){try{this.wait();

}catch(InterruptedException e) {

e.printStackTrace();

}

}

index--;this.notifyAll();

System.out.println("消费者从"+ index+ "位置取出:" + this.products[index]);return this.products[index];

}

}

大致流程:生产者每次产生一个产品,消费者一次消费一个产品; 仓库容量有限,当满存的时候,生产者就需要等待,直到有消费者消费,才被唤醒; 如果仓库是空的,那么消费者就不能消费,要等待,知道生产者生产出一个产品,并唤醒消费者。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值