13章笔记及代码1Word文档格式.docx
《13章笔记及代码1Word文档格式.docx》由会员分享,可在线阅读,更多相关《13章笔记及代码1Word文档格式.docx(13页珍藏版)》请在冰豆网上搜索。
{
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{
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
System.out.println();
printnumber
*/
classPrintNumberThreadextendsThread{
System.out.println("
0000000000000000000000000000000000000000000000"
2.实现runnable接口
classPrintNumberThreadimplementsRunnable{
启动一个线程:
Runnablet1=newPrintNumberThread();
Threadnumber=newThread(t1);
number.start();
线程的状态,状态之间如何切换?
初始状态--start---可运行状态(就绪状态)------分配cpu----运行状态(如果时间片到期可能回到可运行状态)
--------run--------结束状态
线程阻塞两种方式:
1.如果正在运行的线程调用sleep方法,会进入一个阻塞状态
等到sleep时间已到,重新进入可运行状态
2.第二种方法用thread的join阻塞
注意:
用sleep控制程序阻塞是不准确的,使用join方法可以使程序的控制变得准确。
思考题?
有几个线程?
打印结果是什么?
可否在main方法里面直接调用run方法,这和用start方法有何区别?
TestThreadtt=newTestThread();
tt.run();
System.out.println(Thread.currentThread().getName());
Printedbymainthread"
classTestThreadextendsThread{
staticinti=0;
finalstaticintMAX_I=10;
while(i<
MAX_I){
System.out.println(i++);
线程阻塞(join方式)
在一个线程里面持有另一个线程对象,调用对方的join方法,就会让当前线程处于等待,一直等到对方线程运行结束,才开始当前线程的运行。
线程状态
初始化------可运行---------------运行-------------结束
处在运行状态的线程可以进入阻塞,当阻塞解除的时候进入可运行状态,阻塞有两种方式:
不精确的方式是sleep,还有一种调用另一个线程对象的join方法,当另一个线程执行完,再解除当前线程的阻塞。
线程的同步
线程的同步:
什么叫多线程?
同时对一个资源操作会有什么问题?
多个线程操作同一个临界资源可能会出现访问冲突或者临界值不符合预期要求的情况,这个时候
我们可以使用synchronized块对其进行包围。
注意里面的参数是一个对象。
有两种方式:
1.synchronized(lock)
publicvoiddeposit(doublecount)throwsInterruptedException{
存入的金额:
+count);
synchronized(lock){
doublenow=balance+count;
Thread.sleep(100);
//存钱操作用时0.1秒钟
balance=now;
存入后金额:
+balance);
publicvoidwithdraw(doublecount)throwsInterruptedException{
取出金额:
doublenow=balance-count;
Thread.sleep(200);
//取钱操作用时0.2秒钟
取出后金额:
2.在方法前面直接加上synchronized
publicsynchronizedvoiddeposit(doublecount)throwsInterruptedException{
doublenow=balance+count;
Thread.sleep(100);
balance=now;
publicsynchronizedvoidwithdraw(doublecount)throwsInterruptedException{
doublenow=balance-count;
Thread.sleep(200);
注意,如果多个线程出现需要使用多个锁的情况,需要在任何方法中保持锁的顺序一致。
才不至于出现死锁。
synchronized(lock1){
synchronized(lock2){
balance=now;
System.out.println("
}
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
publicclassCard{
privateObjectlock=newObject();
privatedoublebalance;
publicdoublegetBalance(){
returnbalance;
publicvoidsetBalance(doublebalance){
this.balance=balance;
*withdraw
publicvoidwithdraw(doublemoney){
while(true)
{
synchronized(this)
当前用户取款金额是:
+money);
doublenow=balance-money;
try{
}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);
取款后的余额是:
+this.balance);
this.notifyAll();
//通知所有在this上等待的线程可以开始执行
}//syn
}//while
*deposit
publicvoiddeposit(doublemoney){
while(true)
synchronized(this){
当前用户存款金额是:
//判断如果now大于2000,在这里等待,等到this.banlance+100
while(this.balance+money>
2000){
this.setBalance(this.balance+money);
存款后的余额是:
}//synchr
*存款线程
classDepositThreadextendsThread{
privateCardcard;
publicDepositThread(Cardcard){
this.card=card;
card.deposit(100);
/**
取款线程
classWithdrawThreadextendsThread{
publicWithdrawThread(Cardcard){
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{
longtotal=0;
//存储综合
//1.创建数组,赋值随机数
int[]big=newint[30000000];
Randomr=newRandom();
30000000;
i++){
big[i]=r.nextInt(100);
//2.计算大数组元素的和
ExecutorServicepool=Executors.newCachedThreadPool();
6;
intstart=i*5000000;
intend=(i+1)*5000000;
SumThreadtask=newSumThread(big,start,end);
Future<
Long>
f=pool.submit(task);
longpart=f.get();
total+=part;
total:
+total);
SumThread.java
importjava.util.concurrent.Callable;
publicclassSumThreadimplementsCallable<
privateint[]big;
privateintstart;
privateintend;
publicSumThread(int[]big,intstart,intend){
this.big=big;
this.start=start;
this.end=end;
publicLongcall()throwsException{
longsum=0;
for(inti=start;
end;
sum+=big[i];
returnsum;