Java中的多线程常用方法
来源:互联网 发布:广州周立功单片机 编辑:程序博客网 时间:2024/06/05 17:33
多线程一直是Java的一个重点和难点,前两天小结了一下。
synchronized和Lock
我们都知道ArrayList是非线程安全的,就拿它开刀。下面这个程序简单地展示了synchronized和Lock的用法。
package temp.test;import java.util.ArrayList;import java.util.List;import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock;/** * Created by 10033 on 2017/5/10. */public class ArrayListThreadTest { public static Lock lock=new ReentrantLock(); public static List list=new ArrayList(); public static int doRun(int cou) { while(cou<100000) { //非同步方法 要么死循环 要么抛异常 /*list.add(10); ++cou;*/ //两种同步方式 /*synchronized (list) { list.add(10); ++cou; }*/ lock.lock(); list.add(10); ++cou; lock.unlock(); } return cou; } public static void main(String[] args) { Thread1 thread1=new Thread1(); Thread2 thread2=new Thread2(); thread1.start(); thread2.start(); while(thread1.cou+thread2.cou<200000) { System.out.println(thread1.cou+thread2.cou); } System.out.println(list.size() + " @@@@"); System.out.println(thread1.cou+thread2.cou + " ####"); }}class Thread1 extends Thread { public int cou=0; @Override public void run() { this.cou=ArrayListThreadTest.doRun(cou); }}class Thread2 extends Thread { public int cou=0; @Override public synchronized void run() { this.cou=ArrayListThreadTest.doRun(cou); }}如果不用同步,那么这个程序要么死循环,要么抛数组下标溢出异常。
tryLock
package temp.test;import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock;/** * Created by 10033 on 2017/5/10. */public class LockTest { public static Lock lock=new ReentrantLock(); public static void main(String[] args) { new Thread(new Runnable() { public void run() { boolean flag=false; try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } try {// if(lock.tryLock(1, TimeUnit.SECONDS)) { //设置时间来获得锁 超时则放弃 if(lock.tryLock()) { //第一次没得到就放弃 flag=true; } else { System.out.println("没获得锁"); } } catch (Exception e) { e.printStackTrace(); } finally { if(flag) { //确定锁上了才解锁 lock.unlock(); System.out.println("解锁啦"); } } } }).start(); new Thread(new Runnable() { public void run() { lock.lock(); try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("解锁~~~~"); lock.unlock(); } }).start(); }}lock和tryLock的一个不同是lock是阻塞等待锁资源,而tryLock则是试一试(和它名字一样),如果不行,就放弃。
lockInterruptibly
package temp.test;import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock;/** * Created by 10033 on 2017/5/11. */public class LockInterruptiblyTest { public static Lock lock=new ReentrantLock(); public static void main(String[] args) throws InterruptedException { Thread t1=new Thread(new Runnable(){ @Override public void run() { try {// Thread.sleep(3000); lock.lockInterruptibly(); System.out.println("No Exeception"); while(true);// for(int i=0;i<1000000;i++); } catch (InterruptedException e) { e.printStackTrace(); System.out.println(Thread.currentThread().getName()+" interrupted."); } finally { lock.unlock(); } } }); t1.start(); t1.interrupt();//中断则锁抛异常// Thread.sleep(1000); }}这个和lock一样也是个愣头青,阻塞等待锁,但它所在的线程一旦收到中断信号,它就抛异常。
interrupt
说到中断,那就讲一下interrupt。
package temp.test;import java.util.concurrent.locks.Condition;import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock;/** * Created by 10033 on 2017/5/11. */public class InterruptTest { public static String lock=""; public static Lock locked=new ReentrantLock(); public static Condition condition=locked.newCondition(); public static void main(String[] args) throws InterruptedException { Thread t1=new Thread(new Runnable() { @Override public void run() { /*synchronized (lock) { for(int i=0;i<10;i++) System.out.println("@@"); try { lock.wait(); } catch (InterruptedException e) { e.printStackTrace(); } for(int i=0;i<10;i++) System.out.println("##"); }*/ locked.lock(); for(int i=0;i<10;i++) System.out.println("@@"); try { condition.await(); } catch (InterruptedException e) { e.printStackTrace(); } for(int i=0;i<10;i++) System.out.println("##"); locked.unlock(); } }); t1.start(); Thread.sleep(1000); t1.interrupt();//唤醒阻塞但抛中断异常 /*synchronized (lock) { //唤醒阻塞不抛异常 wait会主动放弃锁资源 lock.notify(); }*/ /*locked.lock(); condition.signal(); locked.unlock();*/ }}
它就是改变一个状态值,它能唤醒阻塞线程(被sleep和wait的),但会抛中断异常。这里还要说一点,那就是wait和notify方法都得在使用该方法的对象的synchronized同步代码块里使用。如:
signal和await
我们都知道Object有wait,notify,notifyAll三个方法,而在Lock机制里,同样有对应的await,signal,signalAll。
package temp.test;import java.util.concurrent.locks.Condition;import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock;/** * Created by 10033 on 2017/5/10. *//** * await和signal必须放在lock之后 */public class SignalAndAwait { public static Lock lock=new ReentrantLock(); //两个Condition来自同一把锁 public static Condition condition1=lock.newCondition(); public static Condition condition2=lock.newCondition(); public static void main(String[] args) { new Thread(new Runnable() { public void run() { for(int i=0;i<50;i++) { lock.lock(); condition2.signal(); System.out.println("Thread1"); try { condition1.await(); } catch (InterruptedException e) { e.printStackTrace(); } finally { lock.unlock(); } } lock.lock(); condition2.signal(); lock.unlock(); } }).start(); new Thread(new Runnable() { public void run() { for(int i=0;i<50;i++) { lock.lock(); condition1.signal(); System.out.println("Thread2"); try { condition2.await(); } catch (InterruptedException e) { e.printStackTrace(); } finally { lock.unlock(); } } lock.lock(); condition1.signal(); lock.unlock(); } }).start(); }}
这三个方法也必须放在它们对应的lock里执行,即获得锁资源后才能执行,不然会抛异常。
yield和join
yield:将当前线程由运行变为就绪。
join:阻塞当前线程,自己开启的线程先运行完再说。
可以看注释,注释写得比较详细
YieldTest
package threadTest;/** * Created by 10033 on 2017/5/19. */public class YieldTest { public static void main(String[] args) { new Thread(new T1()).start(); new Thread(new T2()).start(); }}class T1 implements Runnable { @Override public void run() { System.out.println("T1~~~~~"); Thread.yield(); //从运行到就绪 如果对方线程不争气阻塞了 那我也不客气 接着运行 System.out.println("T1@@@@@"); }}class T2 implements Runnable { @Override public void run() { System.out.println("T266666"); try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("T2T2T2"); }}JoinTest
package threadTest;/** * Created by 10033 on 2017/5/19. */public class JoinTest { public static void main(String[] args) throws InterruptedException { /*Thread t2=new Thread(new T4());// t2.join(); //放在start之前并不会抛异常 但没join效果 t2.start(); t2.join(); //我加入了我就是老大 等我运行完后面的程序才能运行 new Thread(new T3()).start();*/ new Thread(new T3()).start(); //内部有join 说明join只影响当前线程 new Thread(new T4()).start(); }}class T3 implements Runnable { @Override public void run() { System.out.println("T1~~~~~"); System.out.println("T1@@@@@"); }}class T4 implements Runnable { @Override public void run() { System.out.println("T266666"); Thread t=new Thread() { @Override public void run() { try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("success"); } }; t.start(); try { t.join(); } catch (InterruptedException e) { e.printStackTrace(); } /*try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); }*/ System.out.println("T2T2T2"); }}
1 0
- Java中的多线程常用方法
- java多线程-常用方法
- java多线程常用方法
- Java多线程常用方法
- Java多线程之常用方法
- JAVA多线程之常用方法
- Java多线程-线程常用方法
- Java多线程-线程常用方法
- java多线程常用方法简介
- Java中的常用方法
- Java中的常用方法
- Java中的常用方法
- Java中的常用方法
- java中的常用方法
- java多线程 中的join方法
- java多线程中的一些方法
- Java的常用方法--Java多线程机制
- Java多线程使用及常用方法
- Java基础知识【下】
- NSOJ Prime Ring Problem
- Can't convert boolean to string automatically, because the "boolean_format" setting was "true,false"
- python 小项目--手机销售系统
- 前中后缀表达式
- Java中的多线程常用方法
- mysql保留小数点后x位
- 关于NOSQL的讲义
- C# 事件
- Eclipse的使用
- Hibernate3
- 复习
- Windows下直接使用gettimeofday函数
- LPC2478 定时器2和定时器3的启用