13章笔记及代码1.docx

上传人:b****6 文档编号:7044486 上传时间:2023-01-16 格式:DOCX 页数:13 大小:18.92KB
下载 相关 举报
13章笔记及代码1.docx_第1页
第1页 / 共13页
13章笔记及代码1.docx_第2页
第2页 / 共13页
13章笔记及代码1.docx_第3页
第3页 / 共13页
13章笔记及代码1.docx_第4页
第4页 / 共13页
13章笔记及代码1.docx_第5页
第5页 / 共13页
点击查看更多>>
下载资源
资源描述

13章笔记及代码1.docx

《13章笔记及代码1.docx》由会员分享,可在线阅读,更多相关《13章笔记及代码1.docx(13页珍藏版)》请在冰豆网上搜索。

13章笔记及代码1.docx

13章笔记及代码1

什么是线程?

可以看成是程序的一次执行过程,牵扯很少的系统资源。

线程的开发:

线程两种实现方式?

1.继承thread类

publicclassMyFirstThreadextendsThread{

@Override

publicvoidrun(){

//TODOAuto-generatedmethodstub

for(inti=0;i<1000;i++)

{

System.out.println("这是我的第1个线程!

");

}

}

}

应该如何启动该线程,让他开始工作。

Main()

{

Threadt=newMyFirstThread();

t.start();

}

多个线程之间的执行时相互独立的。

启动一个线程用thread对象的start方法。

启动不是马上就执行run方法,要等到cpu分配过来才能执行。

如果直接调用thread的run方法,不会启动一个线程,这时候就会把run方法当成一个普通的方法来执行,这个时候多个线程之间就是按照顺序执行。

举例:

一个打印一串字母,一个打印一串数字,看看两个线程打印情况,让两个线程同时启动。

packagecom.wdp;

publicclassTest{

publicstaticvoidmain(String[]args){

//打印字母的线程

Threadt=newPrintLetterThread();

Threadt1=newPrintNumberThread();

//开启两个线程

t.start();

t1.start();

}

}

/**

*printletter

*@authorchidianwei

*

*/

classPrintLetterThreadextendsThread{

@Override

publicvoidrun(){

//TODOAuto-generatedmethodstub

for(inti=0;i<1000;i++)

System.out.println("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");

System.out.println();

}

}

/**

printnumber

*/

classPrintNumberThreadextendsThread{

@Override

publicvoidrun(){

//TODOAuto-generatedmethodstub

for(inti=0;i<1000;i++)

System.out.println("0000000000000000000000000000000000000000000000");

System.out.println();

}

}

2.实现runnable接口

/**

printnumber

*/

classPrintNumberThreadimplementsRunnable{

@Override

publicvoidrun(){

//TODOAuto-generatedmethodstub

for(inti=0;i<1000;i++)

System.out.println("0000000000000000000000000000000000000000000000");

System.out.println();

}

}

启动一个线程:

Runnablet1=newPrintNumberThread();

//开启两个线程

Threadnumber=newThread(t1);

number.start();

线程的状态,状态之间如何切换?

初始状态--start---可运行状态(就绪状态)------分配cpu----运行状态(如果时间片到期可能回到可运行状态)

--------run--------结束状态

线程阻塞两种方式:

1.如果正在运行的线程调用sleep方法,会进入一个阻塞状态

等到sleep时间已到,重新进入可运行状态

2.第二种方法用thread的join阻塞

注意:

用sleep控制程序阻塞是不准确的,使用join方法可以使程序的控制变得准确。

思考题?

有几个线程?

打印结果是什么?

可否在main方法里面直接调用run方法,这和用start方法有何区别?

publicclassTest{

publicstaticvoidmain(String[]args){

//TODOAuto-generatedmethodstub

TestThreadtt=newTestThread();

tt.run();

System.out.println(Thread.currentThread().getName());

System.out.println("Printedbymainthread");

}

}

classTestThreadextendsThread{

staticinti=0;

finalstaticintMAX_I=10;

@Override

publicvoidrun(){

//TODOAuto-generatedmethodstub

System.out.println(Thread.currentThread().getName());

while(i

System.out.println(i++);

}

}

}

线程阻塞(join方式)

在一个线程里面持有另一个线程对象,调用对方的join方法,就会让当前线程处于等待,一直等到对方线程运行结束,才开始当前线程的运行。

线程状态

初始化------可运行---------------运行-------------结束

处在运行状态的线程可以进入阻塞,当阻塞解除的时候进入可运行状态,阻塞有两种方式:

不精确的方式是sleep,还有一种调用另一个线程对象的join方法,当另一个线程执行完,再解除当前线程的阻塞。

线程的同步

线程的同步:

什么叫多线程?

同时对一个资源操作会有什么问题?

多个线程操作同一个临界资源可能会出现访问冲突或者临界值不符合预期要求的情况,这个时候

我们可以使用synchronized块对其进行包围。

注意里面的参数是一个对象。

有两种方式:

1.synchronized(lock)

publicvoiddeposit(doublecount)throwsInterruptedException{

System.out.println("存入的金额:

"+count);

synchronized(lock){

doublenow=balance+count;

Thread.sleep(100);//存钱操作用时0.1秒钟

balance=now;

}

System.out.println("存入后金额:

"+balance);

}

publicvoidwithdraw(doublecount)throwsInterruptedException{

System.out.println("取出金额:

"+count);

synchronized(lock){

doublenow=balance-count;

Thread.sleep(200);//取钱操作用时0.2秒钟

balance=now;

}

System.out.println("取出后金额:

"+balance);

}

2.在方法前面直接加上synchronized

publicsynchronizedvoiddeposit(doublecount)throwsInterruptedException{

System.out.println("存入的金额:

"+count);

doublenow=balance+count;

Thread.sleep(100);//存钱操作用时0.1秒钟

balance=now;

System.out.println("存入后金额:

"+balance);

}

publicsynchronizedvoidwithdraw(doublecount)throwsInterruptedException{

System.out.println("取出金额:

"+count);

doublenow=balance-count;

Thread.sleep(200);//取钱操作用时0.2秒钟

balance=now;

System.out.println("取出后金额:

"+balance);

}

注意,如果多个线程出现需要使用多个锁的情况,需要在任何方法中保持锁的顺序一致。

才不至于出现死锁。

publicvoiddeposit(doublecount)throwsInterruptedException{

System.out.println("存入的金额:

"+count);

synchronized(lock1){

doublenow=balance+count;

Thread.sleep(100);//存钱操作用时0.1秒钟

synchronized(lock2){

balance=now;

System.out.println("存入后金额:

"+balance);

}

}

}

publicvoidwithdraw(doublecount)throwsInterruptedException{

System.out.println("取出金额:

"+count);

synchronized(lock1){

doublenow=balance-count;

Thread.sleep(200);//取钱操作用时0.2秒钟

synchronized(lock2){

balance=now;

System.out.println("取出后金额:

"+balance);

}

}

}

 

Object的wait,notify和notifyAll

  #调用obj的wait(),notify()方法前,必须获得obj锁,也就是必须写在synchronized(obj){...}代码段内。

  

  #调用obj.wait()后,线程A就释放了obj的锁,否则线程B无法获得obj锁,也就无法在synchronized(obj){...}代码段内唤醒A。

  

  #当obj.wait()方法返回后,线程A需要再次获得obj锁,才能继续执行。

  

  #如果A1,A2,A3都在obj.wait(),则B调用obj.notify()只能唤醒A1,A2,A3中的一个(具体哪一个由JVM决定)。

java新特性之concurrentThread处理多线程问题

●摒弃synchronized

▪java.util.concurrent.locks.LOCK

✓lock()

✓unlock()

✓tryLock()

●摒弃wait()notify()notifyAll()

▪java.util.concurrent.locks.Condition

✓awaite()

✓signal()

signalAll()

线程之间进行合作用到锁的wait和notifyAll

packagecom.wdp;

publicclassCard{

privateObjectlock=newObject();

privatedoublebalance;

publicdoublegetBalance(){

returnbalance;

}

publicvoidsetBalance(doublebalance){

this.balance=balance;

}

/**

*withdraw

*/

publicvoidwithdraw(doublemoney){

while(true)

{

synchronized(this)

{

System.out.println("当前用户取款金额是:

"+money);

doublenow=balance-money;

try{

Thread.sleep(100);

}catch(InterruptedExceptione){

//TODOAuto-generatedcatchblock

e.printStackTrace();

}

while(this.balance-money<0){

try{

this.wait();

}catch(InterruptedExceptione){

//TODOAuto-generatedcatchblock

e.printStackTrace();

}

}

this.setBalance(this.balance-money);

System.out.println("取款后的余额是:

"+this.balance);

this.notifyAll();//通知所有在this上等待的线程可以开始执行

}//syn

}//while

}

/**

*deposit

*/

publicvoiddeposit(doublemoney){

while(true)

{

synchronized(this){

System.out.println("当前用户存款金额是:

"+money);

try{

Thread.sleep(100);

}catch(InterruptedExceptione){

//TODOAuto-generatedcatchblock

e.printStackTrace();

}

//判断如果now大于2000,在这里等待,等到this.banlance+100

while(this.balance+money>2000){

try{

this.wait();

}catch(InterruptedExceptione){

//TODOAuto-generatedcatchblock

e.printStackTrace();

}

}

this.setBalance(this.balance+money);

System.out.println("存款后的余额是:

"+this.balance);

this.notifyAll();

}//synchr

}//while

}

}

/**

*存款线程

*/

classDepositThreadextendsThread{

privateCardcard;

publicDepositThread(Cardcard){

this.card=card;

}

@Override

publicvoidrun(){

//TODOAuto-generatedmethodstub

card.deposit(100);

}

}

/**

取款线程

*/

classWithdrawThreadextendsThread{

privateCardcard;

publicWithdrawThread(Cardcard){

this.card=card;

}

@Override

publicvoidrun(){

//TODOAuto-generatedmethodstub

card.withdraw(50);

}

}

实例代码:

考虑一道淘宝的笔试题:

一个长度的30000的int数组,其中放随机数,利用多核的优势,求数组中元素的和。

TestArray.java

packagecom.exer;

importjava.util.Random;

importjava.util.concurrent.ExecutionException;

importjava.util.concurrent.ExecutorService;

importjava.util.concurrent.Executors;

importjava.util.concurrent.Future;

publicclassTestBigArray{

/*

*一个长度的30000的int数组,其中放随机数,利用多核的优势,求数组中元素的和。

*/

publicstaticvoidmain(String[]args)throwsInterruptedException,ExecutionException{

//TODOAuto-generatedmethodstub

longtotal=0;//存储综合

//1.创建数组,赋值随机数

int[]big=newint[30000000];

Randomr=newRandom();

for(inti=0;i<30000000;i++){

big[i]=r.nextInt(100);

}

//2.计算大数组元素的和

ExecutorServicepool=Executors.newCachedThreadPool();

for(inti=0;i<6;i++)

{

intstart=i*5000000;

intend=(i+1)*5000000;

SumThreadtask=newSumThread(big,start,end);

Futuref=pool.submit(task);

longpart=f.get();

total+=part;

}

System.out.println("total:

"+total);

}

}

SumThread.java

packagecom.exer;

importjava.util.concurrent.Callable;

publicclassSumThreadimplementsCallable{

privateint[]big;

privateintstart;

privateintend;

publicSumThread(int[]big,intstart,intend){

this.big=big;

this.start=start;

this.end=end;

}

@Override

publicLongcall()throwsException{

//TODOAuto-generatedmethodstub

longsum=0;

for(inti=start;i

sum+=big[i];

}

returnsum;

}

}

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高中教育 > 语文

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1