Java中的多线程常用方法
2017-05-11 20:11
274 查看
多线程一直是Java的一个重点和难点,前两天小结了一下。
它就是改变一个状态值,它能唤醒阻塞线程(被sleep和wait的),但会抛中断异常。这里还要说一点,那就是wait和notify方法都得在使用该方法的对象的synchronized同步代码块里使用。如:
signal和await
我们都知道Object有wait,notify,notifyAll三个方法,而在Lock机制里,同样有对应的await,signal,signalAll。
这三个方法也必须放在它们对应的lock里执行,即获得锁资源后才能执行,不然会抛异常。
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");
}
}
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");
}
}
相关文章推荐
- Java多线程之常用方法
- Java多线程总结(2) — 线程生命周期中常用方法
- java多线程(六)-线程的状态和常用的方法
- Java学习笔记—多线程(Java线程常用方法总结)
- Java基础-多线程的中常用方法
- java多线程的常用方法(以及注意事项)
- Java多线程(一些常用方法)
- Java多线程基础之常用方法
- java多线程应用中常用的sleep、yield、join、wait、notify、notifyAll方法介绍
- Java多线程与并发学习之(四):线程常用方法
- java多线程机制三--线程的常用方法
- JAVA基础 day12 线程间通信 多线程一些常用方法
- java多线程的创建及常用方法
- Java多线程常用方法
- java多线程常用方法区别--备忘笔记
- Java 多线程中常用的方法
- 【转】【Thread】Java向线程传递参数的常用方法【多线程】
- Java多线程的常用方法(命名与取得)
- java多线程中几个常用的方法
- Java基础:多线程(1)--线程的概述、创建线程的方式、线程的多种状态、线程常用的方法