多线程(一)

这边来谈谈java中,我对对多线程的理解

在了解多线程前,先说说进程。

进程就是正在运行的应用程序。  当你打开任务管理器的时候,你就会发现很多的进程。

而我们要说的线程,就是依赖于进程而存在的,一个进程可以开启多个线程。

Thread类

说到线程,就必须来说说Thread类。

Thread类是说有线程的父类。具体请参见api

线程的创建以及执行(图解如下)

继承Thread类,或者实现rennable接口。
当继承了父类后,需要重写父类的run方法,这个run方法里面就写你要执行的代码,当这个线程启动的时候,就会执行你重写的run方法里面的内容。上边的图run里面写的是一个for循环,输出的是一到一百。

线程启动:start方法即可实现。
代码实现:开启线程,并启动,输出结果

public class MyThread extends Thread{
	//1.继承Thread类
	//2.重写run方法,重写run方法中的代码之后,当我们启动了这个线程之后,我们的这个线程就会执行run方法中的代码
	public class MyThread extends Thread{
	//1.继承Thread类
	//2.重写run方法,重写run方法中的代码之后,当我们启动了这个线程之后,我们的这个线程就会执行run方法中的代码
	@Override
	public void run() {
		//需求:开启该线程之后,执行一个for循环
		for (int i = 0; i < 10; i++) {
			System.out.println(i);
		}
	}

	//在测试类中启动,来看输出。
	//代码实现
	public class Test {
	public static void main(String[] args) {
		//只要我们创建了一个线程对象,并且启动该线程的实例,我们就相当于开启了一///个线程
		MyThread mt = new MyThread();
		mt.start();//1.开启了一个线程   2.让开启的这个线程执行他对应的类中的run方//法

		//在次创建一个子线程,并开启这个子线程执行他的run方法
		MyThread mt2 = new MyThread();
		mt2.start();

	}

	最终输出的是我们在run方法里写的for循环。

接下来我们用第二种方法,实现一个runnable接,并重写run方法
public class MyThread implements Runnable{
	@Override
	public void run() {
		//启动该线程对象之后,需要执行的代码
		for (int i = 0; i < 10; i++) {
			System.out.println(i);
		}
	}

}
public class MyThread implements Runnable{
	@Override
	public void run() {
		//启动该线程对象之后,需要执行的代码
		for (int i = 0; i < 10; i++) {
			System.out.println(i);
		}
	}

}

public class Test {
	public static void main(String[] args) {
		//创建Mythread对象
		MyThread mt = new MyThread();
		Thread t1 = new Thread(mt);
		t1.start();

	}

}
这就是线程的创建和启动

	线程的调度和控制
		线程休眠(Thread.sleep(毫秒值))
		线程名称(setName(),getName();)
		线程的调度及优先级setPriority(10)(注意默认值是5,区间在1-10之间)
		什么叫线程优先级:说白了就是设置你抢占cpu执行权抢占到的概率

			MyThread t1 = new MyThread();
		MyThread t2 = new MyThread();
		MyThread t3 = new MyThread();

		//给三个线程设置姓名
		t1.setName("刘备");
		t2.setName("张飞");
		t3.setName("关羽");

		//设置线程的优先级
		//线程的调度及优先级setPriority(10)(注意默认值是5,区间在1-10之间)
		//t1.setPriority(100);//设置的区间必须在1-10之间
		t1.setPriority(10);

		//开启线程
		t1.start();
		t2.start();
		t3.start();

	//共有100张票,将ticket改为静态之后,被类的所有对象所共享
	static int ticket = 100;

	@Override
	public void run() {
		//用一个while true循环模拟三个窗口一直处于打开的状态
		while (true) {
			//只有当ticket>0的时候,才可以出售票
			if (ticket>0) {
		System.out.println(getName()+"正在出售第:"+ticket--+"张票");
			}
		}
	}

	public static void main(String[] args) {
		//创建三个线程模拟三个售票窗口
		MyThread mt1 = new MyThread();
		MyThread mt2 = new MyThread();
		MyThread mt3 = new MyThread();

		//给线程设置名称
		mt1.setName("窗口一");
		mt2.setName("窗口二");
		mt3.setName("窗口三");

		//启动线程,开启售票
		mt1.start();
		mt2.start();
		mt3.start();

	}
		以上代码是一个售票案例,是一个多线程的案例。

	这里说到cpu的执行权。下图简单说说,执行权和执行。		

这是那个案例的输出结果,在之后我们会谈到线程不安全性问题。

这里说几点:执行权的抢占是随机的,谁抢到就执行谁,可以通过sleep来验证(详见java相关\第十五天代码+资料)

在使用runnable实现售票案例的时候,在线程睡一会之后,会出现线程安全性问题。

如何解决多线程安全问题

*线程安全执行效率就低

A:同步代码块(测试不是同一个锁的情况,测试是同一个锁的情况)

synchronized(对象) {

需要被同步的代码。

}

需求:1.测试不是同一把锁的时候线程安全吗? 2.如果是同一把锁线程安全吗?

两个问题:1.对象是什么 ?

答:任意对象 ,相当于是一把锁,只要线程进去就把锁锁上

2.需要同步的代码?

答:被线程执行的代码

锁对象问题

a:同步代码


块(定义一个抽象类,里面专门定义一个锁)

任意对象

b:同步方法(仅适用于实现runable接口)

public synchronized void sellTicket(){同步代码}

this

静态同步方法

类的字节码对象

public static synchronized void sellTicket() {

需要同步的代码

}

public class MyThread implements Runnable{
//定义100张票
int ticket = 100;
Object obj = new Object();
@Override
public void run() {
while (true) {
//同步代码块
//synchronized (new Object()) {//t1,t2,t3三个线程不共享同一把锁每个线程都有自己的议案锁
synchronized (obj) {//这样3个线程才可以共享同一把锁
if (ticket>0) {
//考虑到实际的生活中,我们需要给每一个线程加入一定的延迟,模拟一下这种效果
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"正在出售第:"+ticket--+"张票");
}

//当被同步的代码执行完毕之后,t1手里拿着的obj这个锁才会被释放,

//t1,t2,t3重新抢占cpu的执行权,谁抢到了继续拿着obj这个锁,执行同步代码块中的内容

}

}

总之,要解决线程安全性问题,就是上边的方法,关于线程,有好多知识点需要巩固,当然有些东西会在下一次的文章中写(多线程二)。

时间: 2024-10-10 17:00:16

多线程(一)的相关文章

Java多线程学习(吐血超详细总结)

林炳文Evankaka原创作品.转载请注明出处http://blog.csdn.net/evankaka 目录(?)[-] 一扩展javalangThread类 二实现javalangRunnable接口 三Thread和Runnable的区别 四线程状态转换 五线程调度 六常用函数说明 使用方式 为什么要用join方法 七常见线程名词解释 八线程同步 九线程数据传递 本文主要讲了java中多线程的使用方法.线程同步.线程数据传递.线程状态及相应的一些线程函数用法.概述等. 首先讲一下进程和线程

Spring多线程

Spring是通过TaskExecutor任务执行器来实现多线程和并发编程的.使用ThreadPoolTaskExecutor可实现一个基于线程池的TaskExecutor.而实际开发中任务一般是非阻碍的,即异步的,所以我们要在配置类中通过@EnableAsync开启对异步的支持,并通过在实际执行的Bean的方法中使用@Async注解来声明其是一个异步任务. 实例代码: (1)配置类 package com.lwh.highlight_spring4.ch3.taskexecutor; /**

python进阶学习(一)--多线程编程

1. 多线程 概念:简单地说操作系统可以同时执行多个不用程序.例如:一边用浏览器上网,一边在听音乐,一边在用笔记软件记笔记. 并发:指的是任务数多余cpu核数,通过操作系统的各种任务调度算法,实现用多个任务"一起"执行(实际上总有一些任务不在执行,因为切换任务的熟度相当快,看上去一起执行而已) 并行:指的是任务数小于等于CPU核数,即任务真的是一起执行的. 2. 线程 概念:线程是进程的一个实体,是CPU调度和分派的基本单位. threading--单线程执行: 1 import ti

多线程的实现及其安全问题

一.进程和线程概述 1.进程:进程是一个具有独立功能的程序关于某个数据集合的一次运行活动,简单来说开启一个程序就开启了一个进程: 如果开启多个进程,它们之间是由于CPU的时间片在相互的切换: 2.线程:开启一个进程的一个任务,对于多线程:每一个线程都在争夺CPU的执行权(CPU的执行权具有随机性): 如果一个程序的执行路径有多条,那么该线程是多线程;反之,就单线程线程:线程是依赖于进程存在的! 3.Jvm是多线程 -- 至少开启了两条线程 main方法 主线程 gc() 垃圾回收线程 二.多线程

多线程和多进程的区别与联系

1.单进程单线程:一个人在一个桌子上吃菜.2.单进程多线程:多个人在同一个桌子上一起吃菜.3.多进程单线程:多个人每个人在自己的桌子上吃菜. 多线程的问题是多个人同时吃一道菜的时候容易发生争抢,例如两个人同时夹一个菜,一个人刚伸出筷子,结果伸到的时候已经被夹走菜了...此时就必须等一个人夹一口之后,在还给另外一个人夹菜,也就是说资源共享就会发生冲突争抢. 1.对于 Windows 系统来说,[开桌子]的开销很大,因此 Windows 鼓励大家在一个桌子上吃菜.因此 Windows 多线程学习重点

Python有了asyncio和aiohttp在爬虫这类型IO任务中多线程/多进程还有存在的必要吗?

最近正在学习Python中的异步编程,看了一些博客后做了一些小测验:对比asyncio+aiohttp的爬虫和asyncio+aiohttp+concurrent.futures(线程池/进程池)在效率中的差异,注释:在爬虫中我几乎没有使用任何计算性任务,为了探测异步的性能,全部都只是做了网络IO请求,就是说aiohttp把网页get完就程序就done了. 结果发现前者的效率比后者还要高.我询问了另外一位博主,(提供代码的博主没回我信息),他说使用concurrent.futures的话因为我全

多线程下的单例-double check

话不多说直接上代码: public sealed class Singleton { private static Singleton _instance = null; // Creates an syn object. private static readonly object SynObject = new object(); Singleton() { } public static Singleton Instance { get { // Double-Checked Lockin

笔记:多线程

多线程程序在较低的层次上扩展了多任务的概念:一个程序同时执行多个任务,通常每个任务称为一个线程(thread),他是线程控制的简称,可以同时运行一个以上线程的程序称为多线程程序(multithreaded):多线程和多进程有哪些区别呢,本质的区别在于每个进程拥有自己的一整套变量,而线程则是共享数据,Java中启动一个线程的代码如下: // 线程任务的具体实现接口 ????public interface Runnable { public abstract void run(); ????} /

多线程

1.线程的概念? 多线程,就类似与操作系统中的多进程.简单的讲,就是可 以同时并发执行多个任务,处理多件事情.这与我们经常所 谓的边唱边跳,边说边做事一个道理.? 线程是一个轻量级的进程,一个进程中可以分为多个线程. 比起进程,线程所耗费的系统资源更少,切换更加容易 /* * 进程是操作系统中的一个任务,一个程序启动运行,就会创建 * 一个(或多个)进程. * 线程是轻量级的进程.进程会有自己独立的内存空间与资源.一个进程 * 下会存在一个(或多个)线程.线程为进程的执行单元.线程本身不含有 *