JavaSE(九)

JavaSE(九)

一、实现多线程的两个方式

  1. 使用继承的方式
public class test{
	public static void main(String[] args){
		MyThread myThread = new Mythread();
		//启动一个分支线程,开辟新的栈空间,启动线程
		myThread.start();
	}
}
public class MyThread extends Thread{
	//JVM线程调度机制,会自动调用run方法
	public void run(){
	}
}
  1. 实现Runnable接口
public class test{
	public static void main(String[] args){
		//创建一个可以运行的对象
		Runnable r = new Runnable();
		//将可运行的对象封装成一个线程对象
		Thread t = new Thread(r);
		//启动线程
		t.start();
	}
}
public class MyRunnable implements Runnable{
	//JVM线程调度机制,会自动调用run方法
	public void run(){
	}
}
  1. 实现Callable接口
//创建一个“未来任务类”对象,需要给一个Callable接口的实现类对象
FutureTask task = new FutureTask(new Callable(){
	//call相当与run方法,只不过有返回值,也可以抛异常
	public Object call() throws Exception{
		........
		........
		return obj;
	}
});
//创建线程对象
Thread t = new Thread(task);
//启动线程
t.start();

//获取t线程的返回结果,但是导致当前线程阻塞,需要等到t线程运行完才有返回值
Object obj = task.get();

二、多线程常用方法

  1. 线程的名字
MyThread t = new MyThread();
//修改线程的名字
t.setName("tttt");
//获取线程的名字,默认的名字为Thread-0、Thread-1......
t.getName();
  1. 获取当前线程对象
//返回值t就是当前线程对象
Thread t = Thread.currentThread();
//获取名字
t.getName();

  1. 线程的sleep方法
//令当前线程进入阻塞状态5000毫秒(5秒)
Thread.sleep(1000*5);
  1. run方法当中的异常不能throws,只能try,catch,因为子类不能比父类抛出更多的异常
  2. interrupt()
//中断t线程的睡眠,会使sleep报异常
t.interrupt()
  1. 强行终止线程
//强行终止t线程(已过时)
t.stop();

7.合理终止线程

class MyRunable implements Runnable{
	//打一个布尔标记
	boolean run = true;
	
	public void run(){
		.......
		.......
		.......
		//在外部修改run,来终止线程的执行
		if(run){

		}else{
			return;
		}
	}
}
  1. 常见的线程调度模型
    1. 抢占式调度模型
      哪个线程的优先级比较高,抢到的cpu时间片的概率就高一些(java)
    2. 均分式调度模型
      平均分配cpu时间片,每个线程占用的cpu时间片时间长度一样
  2. 调度相关方法
Thread currentThread = Thread.currentThread();
currentThread.start();

//获取优先级
currentThread.getPriority();

//修改线程的优先级,默认5,最高10,最小1
currentThread.setPriority(10);

//让位,当前线程暂停,回到就绪状态,让给其他线程
Thread.yield();

//合并线程
currentThread.join();//将currentThread合并到当前线程中,当前线程阻塞,currentTread线程执行,直到结束
  1. synchronized
//	1. 同步代码块
//线程需要抢到线程共享对象的对象锁才能执行同步代码块
synchronized(共享对象){
   //同步代码块
}

//	2. 在实例方法上
//表示该方法是线程安全的
public synchronized void dosome(){
   
}

//	3. 在静态方法上(找类锁)
public static synchronized void dosome(){

}
  1. 怎么解决线程安全问题
    1. 尽量使用局部变量来代替静态变量和实例变量
    2. 创建多个对象
    3. 使用synchronized
  2. 守护线程
//启动线程之前,将线程设置为守护线程
t.setDaemon(true);

三、定时器

//创建定时器对象
Timer timer = new Timer();

//Timer timer = new Timer(ture);守护线程的方式

timer.schedule(new LogTimeTask,第一次执行的时间,间隔执行的时间);

//定时任务类,TimerTask类实现了Runnable接口
class LogTimerTask extends TimerTask{
	public void run(){
	}
}

四、生产者和消费者模式

  1. wait()和notify() (建立在synchronized线程同步的基础之上)
Object obj = new Object();
//使在obj对象上活动的线程等待,并且释放obj的对象锁
obj.wait();
//使在obj对象上等待的线程唤醒
obj.notify();
  1. 模仿生产者和消费者
public class ThreadTest16 {
    public static void main(String[] args) {
        // 创建1个仓库对象,共享的。
        List list = new ArrayList();
        // 创建两个线程对象
        // 生产者线程
        Thread t1 = new Thread(new Producer(list));
        // 消费者线程
        Thread t2 = new Thread(new Consumer(list));

        t1.setName("生产者线程");
        t2.setName("消费者线程");

        t1.start();
        t2.start();
    }
}

// 生产线程
class Producer implements Runnable {
    // 仓库
    private List list;

    public Producer(List list) {
        this.list = list;
    }
    @Override
    public void run() {
        // 一直生产(使用死循环来模拟一直生产)
        while(true){
            // 给仓库对象list加锁。
            synchronized (list){
                if(list.size() > 0){ // 大于0,说明仓库中已经有1个元素了。
                    try {
                        // 当前线程进入等待状态,并且释放Producer之前占有的list集合的锁。
                        list.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                // 程序能够执行到这里说明仓库是空的,可以生产
                Object obj = new Object();
                list.add(obj);
                System.out.println(Thread.currentThread().getName() + "--->" + obj);
                // 唤醒消费者进行消费
                list.notifyAll();
            }
        }
    }
}

// 消费线程
class Consumer implements Runnable {
    // 仓库
    private List list;

    public Consumer(List list) {
        this.list = list;
    }

    @Override
    public void run() {
        // 一直消费
        while(true){
            synchronized (list) {
                if(list.size() == 0){
                    try {
                        // 仓库已经空了。
                        // 消费者线程等待,释放掉list集合的锁
                        list.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                // 程序能够执行到此处说明仓库中有数据,进行消费。
                Object obj = list.remove(0);
                System.out.println(Thread.currentThread().getName() + "--->" + obj);
                // 唤醒生产者生产。
                list.notifyAll();
            }
        }
    }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值