创建线程
1.继承Thread ,重写里面 run 方法
public class Sell1 extends Thread {
public void run() {
while (true) {
try {
sleep(10);
} catch (Exception e) {
e.printStackTrace();
}
...
}
}
public static void main(String[] args) {
Sell1 sell1 = new Sell1();
Thread thread1 = new Thread(sell1);
thread1.start();
}
}
2.实现runnable 接口, 把实现了runnable接口的对象,放到thread的构造函数里面
public class Sell3 implements Runnable {
public void run() {
while (true) {
try {
Thread.currentThread().sleep(10);
} catch (Exception e) {
e.printStackTrace();
}
...
}
}
public static void main(String[] args) {
Sell3 sell3 = new Sell3();
new Thread(sell3) {}.start();
}
}
3.匿名内部类:两种写法
new Thread() {
// 重写父类的run方法,Thread的子类,没有名字 -> 匿名内部类
public void run() {
}
}.start();
new Thread(new Runnable() {
// 实现接口的方法,接口的子类, 没有名字 -> 匿名内部类
public void run() {
}
}).start();
线程常用的方法
1.类方法(静态):
Thread.sleep(long m); //休眠
Thread.currentThread(); //当前线程
2.对象方法 [ t = new Thread(); ] :
t.start() ; // 开启线程
t.getName(); //得到当前线程的名字
线程安全问题(synchronized同步)
1.线程产生安全问题的原因:
- 多个线程
- 修改公共资源
- run方法内多句代码
2.解决办法
- 同步方法
public synchronized void run() {
while (true) {
try {
Thread.currentThread().sleep(10);
} catch (Exception e) {
e.printStackTrace();
}
}
}
- 同步代码块(同步对象是object , this , 静态类.class)
Object obj = new Object();
public void run() {
while (true) {
synchronized (obj) {
try {
//此处只有一条语句
Thread.currentThread().sleep(10);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
3.同步优缺点 :
耗时但保证了线程安全 ;
单例模式 :
package synchronize;
//单例的原因:构造方法是私有的,我们不能直接new一个对象出来;
public class Singleton {
//恶汉模式:所以我们先自行new一个对象,再用一个公有方法返回这个对象;
// private static Singleton Instance=new Singleton();
//
// public synchronized static Singleton getInstance(){
// return Instance ;
// }
//懒汉模式;一上来只是定义一个对象并不初始化,之后在一个公有方法里初始化它,并返回
private static Singleton instance;
public Singleton getInstance() {
if (instance == null) {// 解决效率问题,所以不写同步方法
synchronized (Singleton.class) {// 解决线程安全问题
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
public static void main(String[] args) {
}
}
死锁问题
1.产生原因:
- 锁的相互嵌套
- 多个线程公用几把锁,拿到锁后互不相让,只有拿到全部的锁才释放
2.死锁产生示例
package synchronize;
public class Dead implements Runnable {
String name;
static String one = new String();//锁1
static String two = new String();//锁2
Dead(String name) {
this.name = name;
}
public void run() {
if ("Ly".equals(this.name)) {
synchronized (one) {
System.out.println("Ly拿到第一把锁");
try {
//因为现在电脑跑得越来越快了,根本锁不住;
//但是增加代码条数或者休眠一段时间可以成功锁住
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (two) {
System.out.println("Ly拿到第二把锁");
}
}
} else {
synchronized (two) {
System.out.println("Xx拿到第二把锁");
synchronized (one) {
System.out.println("Xx拿到第一把锁");
}
}
}
}
public static void main(String[] args) {
Dead dead1 = new Dead("Ly");
new Thread(dead1) {
}.start();
Dead dead2 = new Dead("Xx");
new Thread(dead2) {
}.start();
}
}
wait和sleep
lock和synchronized
public void set() {
lock.lock();//锁住
try {
...
} finally {
lock.unlock();//释放锁,必须执行!!!
}
}
wait , notify , notify all
1.作用:
- wait 会释放cpu,释放锁
- notify 是唤醒一个等待线程,进入可执行状态
- notifyAll 唤醒所有等待池中的线程
锁对象调用 ,必须在同步里面!!
2.java.lang.IllegalMonitorStateException非法监控异常
解决办法:锁对象.wait() , 锁对象.notify();
3.示例:妖的故事
String name;
String sex;
Object lock = new Object();
int x = 0;
class Set implements Runnable {
public void run() {
while (true) {
public synchronized void set() {
if (x == 0) {
name = "男";
sex = "男";
} else {
name = "女";
sex = "女";
}
notify();
try {
wait();//释放CPU和锁
} catch (InterruptedException e) {
e.printStackTrace();
}
x++;
x %= 2;
}
}
}
}
class Get implements Runnable {
public void run() {
while (true) {
public synchronized void get() {
System.out.println(name + " " + sex);
notify(); // 唤醒一个wait等待的线程
try {
wait();//释放CPU和锁
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
public static void main(String[] args) {
Resource resource = new Resource();
Set set = resource.new Set();
Get get = resource.new Get();
new Thread(set).start();
new Thread(get).start();
}
线程池
示例:
package threadPool;
import java.util.ArrayList;
public class MyThreadPool {
static ArrayList<MyTask> list = new ArrayList<MyTask>();
public MyThreadPool(int i) {
for (int j = 0; j < i; j++) {
MyWorkThread thread = new MyWorkThread(list);
}
}
public static void adds(MyTask myTask) {
synchronized (list) {
list.add(myTask);
list.notify();
}
}
}
package threadPool;
import java.util.ArrayList;
public class MyWorkThread implements Runnable {
ArrayList<MyTask> list;
MyWorkThread(ArrayList<MyTask> list) {
this.list = list;
new Thread(this).start();
}
public void run() {
while (true) {
synchronized (list) {
if (list != null && list.size() > 0) {
} else {
try {
list.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
MyTask remove = list.remove(0);
remove.task();
}
}
}
package threadPool;
public class MyTask extends Thread {
String name;
public MyTask(String string) {
name = string;
}
public void task() {
System.out.println(name + Thread.currentThread().getName() + "~~~");
}
}
package threadPool;
public class Test {
public static void main(String[] args) {
MyThreadPool pool = new MyThreadPool(5);
MyTask my = new MyTask("~~");
pool.adds(my);
pool.adds(my);
pool.adds(my);
pool.adds(my);
pool.adds(my);
pool.adds(my);
pool.adds(my);
}
}