- 第一种创建线程的方式:继承Thread并重写run方法来定义线程要执行的任务
public class ThreadDemo1 {
public static void main(String[] args) {
MyThread1 t1=new MyThread1();
MyThread2 t2=new MyThread2();
t1.start();
t2.start();
}
}
class MyThread1 extends Thread{
public void run(){
for(int i=0;i<1000;i++){
System.out.println("你是谁呀?");
}
}
}
class MyThread2 extends Thread{
public void run(){
for(int i=0;i<1000;i++){
System.out.println("我是查水表的");
}
}
}
- 第二种创建线程的方式:实现Runnable接口并重写run方法
public class ThreadDemo2 {
public static void main(String[] args) {
Runnable r1=new MyRunnable1();
Runnable r2=new MyRunnable2();
Thread t1=new Thread(r1);
Thread t2=new Thread(r2);
t1.start();
t2.start();
}
}
class MyRunnable1 implements Runnable{
public void run(){
for(int i=0;i<1000;i++){
System.out.println("你是谁呀?");
}
}
}
class MyRunnable2 implements Runnable{
public void run(){
for(int i=0;i<1000;i++){
System.out.println("我是查水表的");
}
}
}
- 使用匿名内部类来完成方式一和方式二的线程创建
public class ThreadDemo3 {
public static void main(String[] args) {
Thread t1=new Thread(){
public void run(){
for(int i=0;i<1000;i++){
System.out.println("你是谁呀");
}
}
};
t1.start();
Runnable runn=new Runnable() {
public void run() {
for(int i=0;i<1000;i++){
System.out.println("我是查水表的");
}
}
};
Thread t2=new Thread(runn);
t2.start();
}
}
- static Thread currentThread()
获取运行当前方法的线程
public class ThreadDemo4 {
public static void main(String[] args) {
Thread main=Thread.currentThread();
System.out.println("运行main方法的线程是:"+main);
dosome();
Thread t=new Thread(){
public void run(){
Thread t=Thread.currentThread();
System.out.println("自定义线程:"+t);
dosome();
}
};
t.start();
}
public static void dosome(){
Thread t=Thread.currentThread();
System.out.println("运行dosome方法的线程是:"+t);
}
}
- 获取线程相关信息的方法
public class ThreadDemo5 {
public static void main(String[] args) {
Thread main=Thread.currentThread();
long id=main.getId();
System.out.println("id:"+id);
String name=main.getName();
System.out.println("name:"+name);
int priority=main.getPriority();
System.out.println("优先级:"+priority);
boolean isAlive=main.isAlive();
System.out.println("是否存活:"+isAlive);
boolean isDaemon=main.isDaemon();
System.out.println("是否为守护线程:"+isDaemon);
boolean isInterrupted=main.isInterrupted();
System.out.println("是否被中断:"+isInterrupted);
}
}
- 线程优先级:线程的时间片分配完全听线程调度的。线程只能被动的被分配时间,对于线程调度的工作不能干预。但是可以通过提高线程的优先级来达到尽可能干预的目的。 理论上,优先级越高的线程,获取CPU时间片的次数就越多。
public class ThreadDemo6 {
public static void main(String[] args) {
Thread min=new Thread(){
public void run(){
for(int i=0;i<10000;i++){
System.out.println("min");
}
}
};
Thread norm=new Thread(){
public void run(){
for(int i=0;i<10000;i++){
System.out.println("norm");
}
}
};
Thread max=new Thread(){
public void run(){
for(int i=0;i<10000;i++){
System.out.println("max");
}
}
};
min.setPriority(Thread.MIN_PRIORITY);
max.setPriority(Thread.MAX_PRIORITY);
min.start();
norm.start();
max.start();
}
}
- static void sleep(long ms) 线程提供的静态方法sleep可以使运行该方法的线程进入阻塞状态指定毫秒。超时后线程会自动回到RUNNABLE状态。
public class ThreadDemo7 {
public static void main(String[] args) {
SimpleDateFormat sdf=new SimpleDateFormat("HH:mm:ss");
while(true){
System.out.println(sdf.format(new Date()));
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
- 守护线程,又称为后台线程。当一个进程中的所有前台线程都结束时,进程就要结束,若还有后台线程运行,那么后台线程会被强制结束
public class ThreadDemo8 {
public static void main(String[] args) {
Thread rose=new Thread(){
public void run(){
for(int i=0;i<10;i++){
System.out.println("rose:let me go");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
}
System.out.println("rose:aaaaa");
System.out.println("音效:噗通");
}
};
Thread jack=new Thread(){
public void run(){
while(true){
System.out.println("jack:you jump,I jump!");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
jack.setDaemon(true);
rose.start();
jack.start();
}
}
- void join() join方法可以使调用该方法的线程进入阻塞状态,直到该方法所属线程完成工作才会解除调用该方法线程的阻塞状态。join方法一般用来完成多个线程之间的同步工作问题
public class ThreadDemo9 {
public static boolean isFinish=false;
public static void main(String[] args) {
final Thread download=new Thread(){
public void run(){
System.out.println("down:开始下载图片...");
for(int i=1;i<=100;i++){
System.out.println("down:"+i+"%");
try {
Thread.sleep(50);
} catch (InterruptedException e) {
}
}
System.out.println("down:图片下载完毕");
isFinish=true;
}
};
Thread show=new Thread(){
public void run(){
System.out.println("show:开始显示图片...");
try {
download.join();
} catch (InterruptedException e) {
}
if(!isFinish){
throw new RuntimeException("图片没有下载完毕");
}
System.out.println("show:图片显示完毕");
}
};
download.start();
show.start();
}
}
- 多线程并发访问同一资源时,就会形成“抢”的现象。由于线程切换时机不确定,可能导致执行代码顺序的混乱,严重时会导致系统瘫痪。
public class SyncDemo1 {
public static void main(String[] args) {
final Table table=new Table();
Thread t1=new Thread(){
public void run(){
while(true){
int bean=table.getBean();
Thread.yield();
System.out.println(getName()+":"+bean);
}
}
};
Thread t2=new Thread(){
public void run(){
while(true){
int bean=table.getBean();
Thread.yield();
System.out.println(getName()+":"+bean);
}
}
};
t1.start();
t2.start();
}
}
class Table{
private int beans=20;
public synchronized int getBean(){
if(beans==0){
throw new RuntimeException("没有豆子了!");
}
Thread.yield();
return beans--;
}
}
- 同步块: 有效的缩小同步范围可以在保证并发安全的同时尽可能提高并发效率。
public class SyncDemo2 {
public static void main(String[] args) {
final Shop shop=new Shop();
Thread t1=new Thread(){
public void run(){
shop.buy();
}
};
Thread t2=new Thread(){
public void run(){
shop.buy();
}
};
t1.start();
t2.start();
}
}
class Shop{
public void buy(){
Thread t=Thread.currentThread();
try {
System.out.println(t.getName()+":正在挑衣服");
Thread.sleep(5000);
synchronized (t) {
System.out.println(t.getName()+":正在试衣服");
Thread.sleep(5000);
}
System.out.println(t.getName()+":结账离开");
} catch (Exception e) {
e.printStackTrace();
}
}
}
- 静态方法的同步 当一个静态方法被synchronized修饰后,那么该方法即为同步方法,由于静态方法从属类,全局就一份,所以同步的静态方法一定具有同步效果,与对象无关。
public class SyncDemo3 {
public static void main(String[] args) {
final Foo f1=new Foo();
final Foo f2=new Foo();
Thread t1=new Thread(){
public void run(){
f1.dosome();
}
};
Thread t2=new Thread(){
public void run(){
f2.dosome();
}
};
t1.start();
t2.start();
}
}
class Foo{
public synchronized static void dosome(){
try {
Thread t=Thread.currentThread();
System.out.println(t.getName()+":正在运行dosome方法");
Thread.sleep(5000);
System.out.println(t.getName()+":运行dosome方法完毕");
} catch (Exception e) {
e.printStackTrace();
}
}
}
- 互斥锁 synchronized也叫互斥锁,即:使用synchronized修饰多段代码,只要他们的同步监视器对象相同,那么这几段代码间就是互斥关系,即:多个线程不能同时执行这些代码。
public class SyncDemo4 {
public static void main(String[] args) {
final Boo boo=new Boo();
Thread t1=new Thread(){
public void run(){
boo.methodA();
}
};
Thread t2=new Thread(){
public void run(){
boo.methodB();
}
};
t1.start();
t2.start();
}
}
class Boo{
public synchronized void methodA(){
try {
Thread t=Thread.currentThread();
System.out.println(t.getName()+":正在执行A方法");
Thread.sleep(5000);
System.out.println(t.getName()+":运行A方法完毕");
} catch (Exception e) {
e.printStackTrace();
}
}
public synchronized void methodB(){
try {
Thread t=Thread.currentThread();
System.out.println(t.getName()+":正在执行B方法");
Thread.sleep(5000);
System.out.println(t.getName()+":运行B方法完毕");
} catch (Exception e) {
e.printStackTrace();
}
}
}
- 将集合或Map转换为线程安全的
public class SyncDemo5 {
public static void main(String[] args) {
List<String> list=new ArrayList<String>();
list.add("one");
list.add("two");
list.add("three");
list.add("four");
System.out.println(list);
list=Collections.synchronizedList(list);
System.out.println(list);
Set<String> set=new HashSet<String>();
System.out.println(set);
set=Collections.synchronizedSet(set);
System.out.println(set);
Map<String,Integer> map=new HashMap<String,Integer>();
map.put("语文", 98);
map.put("数学", 95);
map.put("英语", 89);
System.out.println(map);
map=Collections.synchronizedMap(map);
System.out.println(map);
}
}
- 线程池 线程池主要有两个作用:1.重用线程 2.控制线程数量。当我们的应用需要创建大量线程或者发现线程会频繁的创建和销毁时就应当考虑使用线程池来维护线程。
public class ThreadPoolDemo {
public static void main(String[] args) {
ExecutorService threadPool=Executors.newFixedThreadPool(2);
for(int i=0;i<5;i++){
Runnable runn=new Runnable() {
@Override
public void run() {
Thread t=Thread.currentThread();
try {
System.out.println(t+":正在运行任务");
Thread.sleep(5000);
System.out.println(t+"运行任务完毕");
} catch (Exception e) {
System.out.println("线程被中断");
}
}
};
threadPool.execute(runn);
System.out.println("指派了一个任务交给线程池");
}
threadPool.shutdownNow();
System.out.println("停止线程池了");
}
}