Java当中的线程

程序:程序是为了完成某个特定任务,使用某种计算机语言编写的一组指令的有序集合。

进程:进程是具有一定独立功能的程序的运行过程,是系统进行资源分配和任务调度的一个独立单位。

线程:线程是进程中的一个独立执行线索,是CPU调度和分配的基本单位,自己基本上不拥有系统资源。

创建线程的四种方式

1、继承Thread类

覆盖定义run方法,启动线程必须是start方法,收到Java当中单根继承体系的影响,一般并不使用。

public static void main(String[] args) {
	MyThread t = new MyThread();
	t.start();
}

2、实现Runnable接口:定义独立类,定义内部类

run方法不能有返回值,不能抛出异常

public static void main(String[] args) {
    Thread t=new Thread(new YyThread());
    t.start();
}

3、使用Callable和Future接口创建线程

Callable接口call方法可以有返回值,可以抛出异常

Future接口的实现FutureTask实现类也实现了Runnable接口

public static void main(String[] args) throws Exception {
		FutureTask[] arr = new FutureTask[10];
		for (int i = 0; i < 10; i++) {
			int begin = i * 100 + 1;
			int end = (i + 1) * 100;
			arr[i] = new FutureTask<>(new MyCallable(begin, end));
			Thread t = new Thread(arr[i]);
			t.start();
		}
		// 获取最终计算结果
		int res = 0;
		for (int i = 0; i < arr.length; i++)
			res += ((Integer) arr[i].get()); // 通过FutureTask提供的get方法获取Callable实现类中call方法的执行结果
		System.out.println("1+2+3+...+1000=" + res);

	}

4、使用线程池创建线程

	public static void main(String[] args) throws Exception{
		ExecutorService es = Executors.newFixedThreadPool(3);
		// 计算1+2+3+...+1000,启动10个工作任务
		Future[] fs = new Future[10];
		for (int i = 0; i < 10; i++) {
			int begin = i * 100 + 1;
			int end = (i + 1) * 100;
			Callable<Integer> caller = new MyCallable(begin, end);
			fs[i] = es.submit(caller);
		}
		int res = 0;
		for (int i = 0; i < fs.length; i++) {
			Object kk = fs[i].get();
			if (kk != null && kk instanceof Integer) {
				res += (Integer) kk;
			}
		}
		es.shutdown();
		System.out.println("1+2+3+...+1000=" + res);

	}

volatile关键字

volatile关键字是Java提供的一种轻量级的同步手段,因为volatile只能保证多线程内存的可见性,不能保证操作的原子性。

volatile 关键字实际上是Java 提供的一种轻量级的同步手段,因为volatile 只能保证多线程内存可见性,不能保证操作的原子性。任何被volatile 修改的变量,都不会进行副本的拷贝,任何操作都即使写在主内存中。因此使用volatile 修改的变量的修改,所有线程都立刻可以看到。

使用volatile 的限制:

1、对变量的写操作不依赖于当前值
2、该变量没有包含在具有其它变量的不变式中

volatile 的特性:

1、保证可见性
2、保证有序性
3、部分原子性,针对volatile 变量的符合操作不具备原子性
 

public calss Test{
    private volatile int a;
    public void add(int count){
        this.a=a+count;
    }
}

sleep方法

Thread类中定义的方法,可以阻塞当前线程,是静态方法。

sleep(long)让当前线程休眠等待指定的时间,单位为ms,如果需要可以通过interrupt方法来唤醒休眠的线程。

例如:实现一个时间显示,每隔一秒钟更新一次显示

public static void main(String[] args) {
	DateFormat fs = new SimpleDateFormat("yyyy-MM-ddE HH:mm:ss");
	while(true){ 
		Date now = new Date();
		String ss = fs.format(now);
		System.out.println(ss);
		try {
			TimeUnit.SECONDS.sleep(1);//休眠一秒,等价于Thread.sleep(1000)
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

提前唤醒休眠的线程:

需要通过interrupt方法实现,会产生一个InterruptedException异常

如:

public static void main(String[] args)throws Exception {
		DateFormat fs = new SimpleDateFormat("yyyy-MM-ddE HH:mm:ss");
		Thread t1 = new Thread(() -> {
			while (true) { 
				Date now = new Date();
				String ss = fs.format(now);
				System.out.println(ss);
				try {
					Thread.sleep(1000);//休眠1s
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
		t1.start();
		Thread.sleep(500);
		t1.interrupt();//用于唤醒处于休眠状态的线程
	}

wait方法

wait方法实在Object类中定义的方法,作用是使当前线程进入等待队列,同时它会使当前线程释放锁持有的锁,直到有其它线程调用此对象的notify或者notifyAll方法进行唤醒

join方法

join方法作用是进行线程的同步处理,可以使得线程之间的并行执行转换为串行执行

synchronized关键字

作用:保证一个时刻点上只有一个线程在执行,不会出现并发的情况,到达排队执行的目的

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值