java io、集合、线程、字符串、gc、jvm可谓是java中的最基本的知识,尤其是线程操作复杂,相应难懂,要想java基础知识扎实,上面提到的几个方面的知识点都要精通,这样方可以称自己掌握java方面基础知识。
总结一下java线程知识,平时接触过线程,尤其是在android开发中,线程可谓是无处不在,稍有不注意就会报错。在java中线程也是无处不在,main就是一个线程,只不过被包装好了,一般接触不到。
我的无数次的复习经历告诉我,学习知识最快,最深刻的方法就是从解题开始,不要先看概念,遇到新知识点,新概念先自己用已有的原始知识解一遍,然后再去看相关解释,会发现,概念是那么的浅显易懂。废话不多说,先上题:
1.用两个线程,交叉输出“123...56”和“abc...z”,要求输出结果为“12a34b67c...5556z”。
分析:此题用到线程同步互斥的知识点。线程1输出->唤醒线程2->线程1等待,线程2输出->唤醒线程1->线程2等待...一直到输出完毕。本题几乎可以全面考察线程互斥的知识。有了这些分析就可以上代码:
/** * * @author mxr *ClassName ThreadTest *@Version 1.0 *@ModifiedBy 2014-10-27 *@Copyright RSDSYST */ public class ThreadTest extends Thread { class Thread1 implements Runnable { private Object _lock; public Thread1(Object lock) { _lock = lock; } @Override public void run() { try { synchronized (_lock) { for (int i = 0; i < 26; i++) { System.out.print((2 * i + 1) + "" + (2 * i + 2)); _lock.notifyAll();//唤醒其他线程 _lock.wait();//释放锁,等待 } } } catch (InterruptedException e) { e.printStackTrace(); } } } class Thread2 implements Runnable { private Object _lock; public Thread2(Object lock) { _lock = lock; } @Override public void run() { synchronized (_lock) { for (int i = 0; i < 26; i++) { System.out.print((char) ('a' + i)); _lock.notifyAll();//叫醒其他线程 if(i<25){ try { _lock.wait();//释放锁,等待 } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } } } public static void main(String[] args){ Object lock=new Object(); Thread t1=new Thread(new ThreadTest().new Thread1(lock)); Thread t2=new Thread(new ThreadTest().new Thread2(lock)); t1.start(); t2.start(); try { t1.join(); t2.join(); } catch (InterruptedException e) { e.printStackTrace(); } } }上面的代码就是按照分析的思想去实现。上面的wait(),notifyAll()都只能用在同步代码块内。
2.用线程实现银行取钱问题,当出现错误时,如何进行同步。
/** * * @author mxr *ClassName ThreadTest *@Version 1.0 *@ModifiedBy 2014-10-27 *@Copyright RSDSYST */ class User{ int sumCount = 100; User(){} public <span style="color:#ff0000;">synchronized</span> void oper(int count){ sumCount = sumCount - count; System.out.println(" has get: "+count+". the sumCount is: "+sumCount); } } public class ThreadTest extends Thread { User user; int useCount; ThreadTest(User user,int useCount){ this.user = user; this.useCount = useCount; } public void run(){ try { sleep(10); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } user.oper(useCount); } public static void main(String[] args){ System.out.println(Thread.currentThread().getName()+" is running"); User user = new User(); ThreadTest tt = new ThreadTest(user,30); ThreadTest tt1 = new ThreadTest(user,20); ThreadTest tt2 = new ThreadTest(user,30); ThreadTest tt3 = new ThreadTest(user,10); tt.start(); tt1.start(); tt2.start(); tt3.start(); System.out.println(Thread.currentThread().getName()+" is end"); } }代码如上,当在oper上不加synchronized时,出现的结果是错误的,因为在同一时间访问了money,加上同步之后,一个时刻只能有一个访问,所以避免了错误。
3.简单的对线程池的理解和应用。
线程池用ExecutorService和Executors来建立,为程序提供线程,当线程很多时,可以大大的节省内存空间,线程池是一个线程队列,当队列的容量小时,多出来的线程就会排队等待。
用容量为2的线程池来实现银行取款问题:
import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; /** * * @author mxr *ClassName ThreadTest *@Version 1.0 *@ModifiedBy 2014-10-27 *@Copyright RSDSYST */ class User{ int sumCount = 100; User(){} public <span style="color:#ff0000;">synchronized</span> void oper(int count){ sumCount = sumCount - count; System.out.println(" has get: "+count+". the sumCount is: "+sumCount); } } public class ThreadTest extends Thread { User user; int useCount; ThreadTest(User user,int useCount){ this.user = user; this.useCount = useCount; } public void run(){ try { sleep(30); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } user.oper(useCount); } public static void main(String[] args){ System.out.println(Thread.currentThread().getName()+" is running"); User user = new User(); ThreadTest tt = new ThreadTest(user,30); ThreadTest tt1 = new ThreadTest(user,20); ThreadTest tt2 = new ThreadTest(user,30); ThreadTest tt3 = new ThreadTest(user,10); ExecutorService pool = Executors.newFixedThreadPool(4); pool.execute(tt); pool.execute(tt1); pool.execute(tt2); pool.execute(tt3); System.out.println(Thread.currentThread().getName()+" is end"); } }同样的,线程池自身是没有同步的,对共享块需要自己用synchronized来控制同步。
原文地址:http://blog.csdn.net/renxyz/article/details/40506279