JAVA多线程学习

java 线程有两类:

1、用户线程执行结束线程自动关闭

2、守护线程 ,由操作系统或用户创建,独立于jvm


直接调用run()并不能启动新线程,必须要运行start(),执行一系统动作,才会启用新线程。

线程优先级与线程让步通过yield()来实现.当设计多线程程序时,一定不要依赖于线程优先级,因为这是没保证的。

Thread.yield()方法作用是:暂停当前正在执行的线程对象,并执行其它线程。yield()从未导至线程转到待待、睡眠、阻塞状态,yield()争导至线程 从运行状态转到可运行状态,但有可能没效果。




Thread 的非静态方法join(),让一个线程B加到线程A的尾部。在A执行完毕之前B不能工作


同步与锁

java每个对象都有一个内置锁,当程序运行与非静态synchronized同步方法时,自动获得与正在执行代码类的当前实例(this)有关锁,在对象上锁定。释放锁是指线程退出synchronized()块。关于锁与对象:

1、只能同步方法,不能同步类与变量。

2、每个对象只有一个锁。

3、线程睡眠时,当持有的所有锁都不会释放

4、同步损害并发,应该尽量宿小使用范围



要 同步静态方法,需要一个用于整个类的同步锁

public static synchronized int setName(String vname){

  xx.name=vname;

}

等同于

public static int setName(String vname){

synchronized (XXX.class){

            xx.name=vname;

       }

 

}

如果线程试图进入同步锁,而其锁被占用,则线程在该对象上被阻塞。

何时需要同步

在多线程访问互斥数据时,则需要需要同步以保护数据。


死锁

当两个线程被阻塞,每个线程在等待另一个线程时,就发生死锁。



线程的交互

java.lang.Object对象的

void notify()  呼醒在此对象上等待的单个线程
void notifyAll()  呼醒在此对象上等待的所有线程

void wait() 使当前线程等待,等待其它线程调此对象的notify或notifyall

例子

package stud.com.peidw;


public class ThreadB extends Thread{
int total;
public void run(){
synchronized(this){
for(int i=1;i<101;i++){
total=total+1;
}
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
notify();
}
}


}

package stud.com.peidw;


public class ThreadA {


public static void main(String[] args) {
// TODO Auto-generated method stub
ThreadB b=new ThreadB();
b.start();
synchronized(b){
System.out.println("等待对象b计算完成...");
try {
b.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

System.out.println("总和:"+b.total);
}


}


java线程调度---休眠

java线程调度---优先级

java线程调度---让步

java线程调度---合并 用join

java线程调度---守护线程

线程启动用,调用setDaemon(boolean on) 把该线程标记录守护线程或用户线程。为true 标志为守护线程。

前台线程执行完,程序退出,不管守护线程的状态。


java线程调度---同步

线程同步是保证多线程安全访问竞争资源的唯 一方法。对于同步,在具体java代码里:

把竞争资源标识为private

同步那些修改资源的代码,使用synchronized,线程同步例子。





package stud.com.peidw;


import stud.com.peidw.beans.User;


public class TestCash {


public static void main(String[] args) {
// TODO Auto-generated method stub
User user=new User("裴", 100);
MyCashThread t1=new MyCashThread("线程A",user,20);
MyCashThread t2=new MyCashThread("线程B",user,-60);
MyCashThread t3=new MyCashThread("线程C",user,40);
MyCashThread t4=new MyCashThread("线程D",user,45);
MyCashThread t5=new MyCashThread("线程E",user,-20);

t1.start();
t2.start();
t3.start();
t4.start();
t5.start();

}


}

package stud.com.peidw;


import stud.com.peidw.beans.User;


public class MyCashThread extends Thread{
private User user;
private int y=0;

public MyCashThread(String name,User u,int y){
super(name);
this.user=u;
this.y=y;
}

public void  run(){
user.oper(y);
}
}




package stud.com.peidw.beans;


public class User {
private String code;
private int cash;

public User(String vcode,int vcase){
this.code=vcode;
this.cash=vcase;
}


public String getCode() {
return code;
}


public void setCode(String code) {
this.code = code;
}

public synchronized void oper(int x){
try{
Thread.sleep(1000L);
this.cash+=x;
System.out.println(Thread.currentThread().getName()+"运行结束,增加 "+x+",当前余额 为:"+cash);
Thread.sleep(1000L);
}catch(Exception e){
e.printStackTrace();
}
}

public String toString(){
return "code="+code+",cash="+cash;
}

}


同步方法中,还可以可以使用特定的方法对线程进行调度,如notify,notifyall,wait





java 5 线程池

线程池说白了就是对象池的思想,开辟一块内存空间,里面存放众多未死线程。池中线程的执行调度由池管理器来处理。java5 线程池有多种,分为固定尺寸线程池,可变尺寸线程池。


package stud.com.peidw;
import java.util.concurrent.*;
public class FixThreadDemo {

public static void main(String[] args) {
// TODO Auto-generated method stub
//ExecutorService pool=Executors.newFixedThreadPool(2);  // 固定线程池
//ExecutorService pool=Executors.newSingleThreadExecutor(); //单线程池
//ExecutorService pool=Executors.newCachedThreadPool(); //可变尺寸线程池
ScheduledExecutorService pool=Executors.newScheduledThreadPool(5); //延时线程池
MyThread1 t1=new MyThread1();
MyThread1 t2=new MyThread1();
MyThread1 t3=new MyThread1();
MyThread1 t4=new MyThread1();
MyThread1 t5=new MyThread1();
MyThread1 t6=new MyThread1();
MyThread1 t7=new MyThread1();
pool.execute(t1);
pool.execute(t2);
pool.execute(t3);
pool.execute(t4);
pool.execute(t5);

pool.schedule(t6,10,TimeUnit.MILLISECONDS);
pool.schedule(t7,10,TimeUnit.MILLISECONDS);

pool.shutdown();
}


}


class MyThread1 extends Thread{
@Override
public void run(){
System.out.println("正在执行:"+Thread.currentThread().getName());
}
}




自定义线程池:

package stud.com.peidw;


import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;


public class CustomThreadPool {


public static void main(String[] args) {
// TODO Auto-generated method stub
BlockingQueue<Runnable> bqueue=new ArrayBlockingQueue<Runnable>(20);
ThreadPoolExecutor pool=new ThreadPoolExecutor(2,3,2,TimeUnit.MILLISECONDS,bqueue);
MyThread2 t1=new MyThread2();
MyThread2 t2=new MyThread2();
MyThread2 t3=new MyThread2();
MyThread2 t4=new MyThread2();
MyThread2 t5=new MyThread2();
MyThread2 t6=new MyThread2();
MyThread2 t7=new MyThread2();
pool.execute(t1);
pool.execute(t2);
pool.execute(t3);
pool.execute(t4);
pool.execute(t5);
pool.execute(t6);
pool.execute(t7);


pool.shutdown();
}


}


class MyThread2 extends Thread{
@Override
public void run(){
System.out.println("正在执行:"+Thread.currentThread().getName());
}
}


有返回值的线程

要想让线程有返回值,需要实现Callable接口,执行 Callable任务后,可以获取一个Future的对象,该对象上get就可以取到Callable返回的对象。


package stud.com.peidw;


import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;


public class CallableDemo {


public static void main(String[] args) throws Exception, ExecutionException {
// TODO Auto-generated method stub
ExecutorService pool= Executors.newFixedThreadPool(2);
Callable c1=new MyCallable("c1");
Callable c2=new MyCallable("c2");
Future f1=pool.submit(c1);
Future f2=pool.submit(c2);
System.out.println(f1.get().toString());

pool.shutdown();
}


}


class MyCallable implements Callable{
private String old;
public MyCallable(String vold){
this.old =vold;
}
@Override
public Object call() throws Exception {

return old+"任务返回的内容";
}

}


java 5线程锁


package stud.com.peidw;


import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;


public class LockDemo {


public static void main(String[] args) {
MyCount  myCount=new MyCount("95599000001",4440);//并发访问的账户
Lock lock=new ReentrantLock();
ExecutorService pool=Executors.newCachedThreadPool();
XUser u1=new XUser("裴一",myCount,-440,lock);
XUser u2=new XUser("裴二",myCount,1000,lock);
XUser u3=new XUser("裴三",myCount,2000,lock);

pool.execute(u1);
pool.execute(u2);
pool.execute(u3);

}


}




class XUser implements Runnable{
private String name;
private MyCount  myCount;
private int iocash;
private Lock myLock;

public  XUser(String name,MyCount myCount,int iocash,Lock mylogck){
this.name=name;
this.myCount=myCount;
this.iocash=iocash;
this.myLock=mylogck;
}

@Override
public void run() {
myLock.lock();
System.out.println(name+"正在操作"+myCount+"账户,金额为"+iocash+",当前金额为"+myCount.getCash());
myCount.setCash(myCount.getCash()+iocash);
System.out.println(name+"操作"+myCount+"账户成功,金额为"+iocash+",当前金额为"+myCount.getCash());
myLock.unlock();
}

}


class MyCount{
private String oid;
private int cash;

public MyCount(String oid,int cash){
this.oid=oid;
this.cash=cash;
}


public String getOid() {
return oid;
}


public void setOid(String oid) {
this.oid = oid;
}


public int getCash() {
return cash;
}


public void setCash(int cash) {
this.cash = cash;
}

public String toString(){
return "MyCount{oid="+oid+" , cash="+cash+"}";
}

}


阻塞队列

package stud.com.peidw;


import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;


public class BlockingQueueDemo {


public static void main(String[] args) throws InterruptedException {
BlockingQueue bqueue=new ArrayBlockingQueue(20);
for (int i=0;i<30;i++){
bqueue.put(i);
System.out.println("向队例中加入:"+i+"无素");
}
System.out.println("程序结束");
}


}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值