http://houlinyan.iteye.com/blog/1112535
http://www.mamicode.com/info-detail-517008.html
http://blog.csdn.net/vernonzheng/article/details/8288251
学了很久的java,但是一直对多线程这块知识不是很熟悉,看了以上博客决定来做个多线程总结,首先立个列表:
多线程零零碎碎的各种概念知识
死锁和数据不一致的现象
synchronized 和 volatile 的区别
synchtonized 和 Reentrantlock的区别
一.多线程的基本概念
这里我需要总结下sleep() ,wait(),yield()的区别
1. sleep()和wait() 的区别
sleep()使线程进入休眠状态,经过一定时间后会回到可运行状态(不是运行状态);而wait()被挂起后必须经过notify()或是notifyAll()唤醒才能进入可运行状态。
sleep()不会释放锁,所以若是A线程陷入睡眠,B线程必须等到A睡醒执行完释放锁才能得到锁;而wait() 会释放锁让其他线程得到锁。
sleep()和wait()都需要抛出InterruptedException异常,但是sleep()属于Thread类,而wait()属于Object类。
2.sleep()和yield()的区别
若A 线程调用sleep()期间,会释放资源让其他线程(不管优先级)得到资源执行;若是A线程调用了yield()方法,也会释放资源让其他线程执行,但是必须是优先级比A高或是相等优先级的线程,所以若是在这个进程中都是优先级都比A低的线程,那么在执行了yield()之后,A线程可能也会得到资源回到运行状态。
yeild()方法不会抛出InterruptedException 异常,而sleep()会。
4 多线程的实现
通常情况下,多线程有两种实现方式
继承Thread
实现Runnable
下面我用代码的方式区分下两者的不同:
public class ImplementsRunnable implements Runnable {
@Override
public void run() {
System.out.println("implements Runnable");
}
}
public class ExtendsThread extends Thread{
private int flag;
public ExtendsThread(int flag){
this.flag=flag;
}
@Override
public void run() {
try {
Thread.sleep(1000);
System.out.println("extends Thread");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
5 多线程的同步
在讲同步前我们先来看个造成数据不一致的例子
import java.util.ArrayList;
import annotation.main;
public class DataNoSame {
static boolean falg=true;
static ArrayList<Integer> list=new ArrayList();
public static void main(String[] args){
DataNoSame da=new DataNoSame();
Thread1 t1=da.new Thread1();
Thread2 t2=da.new Thread2();
new Thread(t1).start();
new Thread(t2).start();
}
class Thread1 implements Runnable{
@Override
public void run() {
list.add(12);
if(list.size()>0){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(list.get(0));
}
}
}
class Thread2 implements Runnable{
@Override
public void run() {
list=null;
}
}
}
上述的代码结果是:
Exception in thread "Thread-0" java.lang.NullPointerException
at thread.DataNoSame$Thread1.run(DataNoSame.java:27)
at java.lang.Thread.run(Thread.java:745)
最后会抛出个空指针异常,因为Thread1在执行到if语句时被Thread2抢占了cpu 先执行了list=null,Thread2 执行完后将资源重新给了Thread1 ,Thread1 继续执行if后面的语句,这时的list 已经为空了,所以会抛出异常。
如何解决这个问题呢?
接下来就讨论多线程同步的问题了。
sysnchronized
public class ThreadSync extends Thread{
private int no;
//private static Object lock=new Object();
public ThreadSync(int no){
this.no=no;
}
public void run(){
synchronized (ThreadSync.class) {
for (int i = 0; i < 4; i++) {
try {
Thread.sleep(1000);
System.out.println("Thread" + no +" "+ i);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
同步方法:
private static synchronized void fun(int no){
for (int i = 1 ; i < 4; i++) {
try {
//Thread.sleep(1000);
System.out.println("Thread" + no +" "+ i);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
synchornized是持有对象锁,单一个线程获得一个对象锁则另一个线程等这个线程结束才能获得锁得到执行。这样借用synchronied 就能解决上述的数据不一致情况了。
volatile
public class volatileTest {
public static void main(String[] args) throws InterruptedException{
Thread1[] t1=new Thread1[100];
Thread2[] t2=new Thread2[100];
for(int i=0;i<100;i++){
t1[i]=new Thread1();
t2[i]=new Thread2();
}
for(int i=0;i<100;i++){
new Thread(t1[i]).start();
new Thread(t2[i]).start();
}
System.out.println("count="+Thread1.count);
System.out.println("count2="+Thread2.count2);
}
}
class Thread1 implements Runnable{
volatile static int count=0;
@Override
public void run() {
for(int i=0;i<100;i++){
count++;
}
}
}
class Thread2 implements Runnable{
static int count2=0;
@Override
public void run() {
synchronized(this){
for(int i=0;i<100;i++){
count2++;
}
}
}
}
写了个代码来区分synchronized和volatile的区别
ReentrantLock
package thread;
/**
* 生产者和消费者问题
* synchronized 实现
*/
import java.util.ArrayList;
public class _1Produdcer_Customer {
private static ArrayList
list=new ArrayList();
final static Integer producter=1;
final static Integer customer=2;
final static private int NUM=10;
static class Producer implements Runnable{
private String name;
private int count=0;
public Producer(String name) {
super();
this.name = name;
}
public void production(){
synchronized (producter) {
if (list.size() < NUM) {
list.add(this.name + " " + ++count+ "0001");
System.out.println(this.name + " produced " + count + "0001");
producter.notifyAll();//唤醒等待生产的消费者
} else {
try {
System.out.println("生产已满 ,等待消费");
producter.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
@Override
public void run() {
production();
}
}
static class Customer implements Runnable{
private String name;
private int count=0;
public Customer(String name) {
super();
this.name = name;
}
public void customtion(){
synchronized (customer) {
try {
Thread.sleep(500);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
if (list.size() > 0) {
System.out.println(this.name + "customed " + list.remove(0));
customer.notifyAll();//唤醒等待消费的生产者
} else {
try {
System.out.println("消费完毕 ,等待生产");
customer.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
@Override
public void run() {
customtion();
}
}
public static void main(String[] args){
Producer[] p=new Producer[10];
Customer[] c=new Customer[10];
for(int i=0;i<10;i++){
p[i]=new Producer("生产者"+i);
c[i]=new Customer("消费者"+i);
}
for(int i=0;i<10;i++){
new Thread(p[i]).start();
new Thread(c[i]).start();
}
}
}
package thread;
/**
* 生产者和消费者问题
* ReentrantLock,condition 实现
*/
import java.util.ArrayList;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class _2Produdcer_Customer {
private static ArrayList
list=new ArrayList();
final static Lock lock=new ReentrantLock();
final static Condition notEmpty=lock.newCondition();
final static Condition notFull=lock.newCondition();
final static private int NUM=10;
static class Producer implements Runnable{
private String name;
private int count=0;
public Producer(String name) {
super();
this.name = name;
}
public void production(){
lock.lock();
try {
if (list.size() < NUM) {
list.add(this.name + " " + ++count + "0001");
System.out.println(this.name + " produced " + count + "0001");
notEmpty.signalAll();
} else {
System.out.println("生产已满 ,等待消费");
notFull.await();
}
}catch(Exception e){
e.printStackTrace();
} finally {
lock.unlock();
}
}
@Override
public void run() {
production();
}
}
static class Customer implements Runnable{
private String name;
private int count=0;
public Customer(String name) {
super();
this.name = name;
}
public void customtion(){
lock.lock();
try{
Thread.sleep(500);
if (list.size() > 0) {
System.out.println(this.name + "customed " + list.remove(0));
notFull.signalAll();
} else {
System.out.println("消费完毕 ,等待生产");
notEmpty.await();
}
}catch(Exception e){
e.printStackTrace();
}finally{
lock.unlock();
}
}
@Override
public void run() {
customtion();
}
}
public static void main(String[] args){
Producer[] p=new Producer[10];
Customer[] c=new Customer[10];
for(int i=0;i<10;i++){
p[i]=new Producer("生产者"+i);
c[i]=new Customer("消费者"+i);
}
for(int i=0;i<10;i++){
new Thread(p[i]).start();
new Thread(c[i]).start();
}
}
}