一、实现多线程的方式
1.继承Thread类
步骤:
A:自定义MyThread类继承Thread类;
B:重写run()方法,包含被线程执行的代码;
C:创建对象;
D:启动线程
package thread;
public class ThreadPriority extends Thread{
@Override
public void run() {
// TODO Auto-generated method stub
for(int i = 0; i < 100; i++){
System.out.println(getName()+"--"+i);
}
}
}
package thread;
public class ThreadPriorityDemo {
public static void main(String[] args) {
ThreadPriority tp1 = new ThreadPriority();
ThreadPriority tp2 = new ThreadPriority();
ThreadPriority tp3 = new ThreadPriority();
//设置线程优先级,最大值为10,最小为1,默认为5
tp1.setPriority(10);
tp2.setPriority(1);
//start()方法启用线程
tp1.start();
tp2.start();
tp3.start();
}
}
2.实现Runnable接口
步骤:
A:自定义类MyRunnable实现Runnable接口;
B:重写run()方法;
C:创建MyRunnable类的对象;
D:创建Thread类对象,把上一步创建的类对象当作构造参数
package thread;
public class MyRunnable implements Runnable {
@Override
public void run() {
// TODO Auto-generated method stub
for(int i = 0; i < 100; i++){
System.out.println(Thread.currentThread().getName()+":"+i);
}
}
}
package thread;
public class MyRunnableDemo {
public static void main(String[] args) {
MyRunnable my = new MyRunnable();
Thread t1 = new Thread(my);
Thread t2 = new Thread(my);
t1.start();
t2.start();
}
}
二、多线程模拟出售电影票
1.使用同步解决线程安全问题
package thread;
public class SellTicket implements Runnable{
//定义100张票
private int tickets = 100;
//定义同一把锁
private Object obj = new Object();
@Override
public void run() {
while(true){
//同步
synchronized (obj) {
if(tickets > 0){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"正在出售第"+(tickets--)+"张票");
}
}
}
}
}
package thread;
public class SellTicketDemo {
public static void main(String[] args) {
SellTicket st = new SellTicket();
Thread t1 = new Thread(st,"窗口1");
Thread t2 = new Thread(st,"窗口2");
Thread t3 = new Thread(st,"窗口3");
t1.start();
t2.start();
t3.start();
}
}
还可以把同步代码块写成同步方法,这时锁对象是这个方法--this。//synchronized (this)
package thread;
public class SellTicket implements Runnable{
//定义100张票
private int tickets = 100;
//定义同一把锁
private Object obj = new Object();
@Override
public void run() {
while(true){
sellTicket();
}
}
private synchronized void sellTicket(){
if(tickets > 0){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"正在出售第"+(tickets--)+"张票");
}
}
}
当方法时静态时,锁对象是类的字节码文件对象,即当前类的class文件。 //synchronized(SellTicket.class)
package thread;
public class SellTicket implements Runnable{
//定义100张票
private static int tickets = 100;
//定义同一把锁
private Object obj = new Object();
@Override
public void run() {
while(true){
sellTicket();
}
}
private static synchronized void sellTicket(){
if(tickets > 0){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"正在出售第"+(tickets--)+"张票");
}
}
}
2.使用lock解决线程安全问题
package thread;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class SellTicketLock implements Runnable{
private int tickets = 100;
private Lock lock = new ReentrantLock();
@Override
public void run() {
while(true){
try{
lock.lock(); //加锁
if(tickets > 0){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"正在出售第"+(tickets--)+"张票");
}
}finally{
lock.unlock();
}
}
}
}
package thread;
public class SellTicketDemo {
public static void main(String[] args) {
SellTicketLock st = new SellTicketLock();
Thread t1 = new Thread(st,"窗口1");
Thread t2 = new Thread(st,"窗口2");
Thread t3 = new Thread(st,"窗口3");
t1.start();
t2.start();
t3.start();
}
}
把不安全的list集合安全的使用:
List<String> list1 = new ArrayList<String>(); //线程不安全
List<String> list2 = Collections.synchronizedList(new ArrayList<String>()); //线程安全
三、生产者消费者之等待唤醒机制
package pv;
public class Student {
private String name;
private int age;
private boolean flag; //默认为false,若为true,则有数据
public synchronized void set(String name,int age){
//若果有数据,就等待
if(this.flag){
try {
this.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//设置数据
this.name = name;
this.age = age;
//修改标记
this.flag = true;
this.notify();
}
public synchronized void get(){
//如果没有数据,就等待
if(!this.flag){
try {
this.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println(this.name+"---"+this.age);
this.flag = false;
this.notify();
}
}
package pv;
public class Set implements Runnable{
private Student s;
private int x = 0;
public Set(Student s){
this.s = s ;
}
@Override
public void run() {
while(true){
if(x % 2 == 0){
s.set("yj", 23);
}else{
s.set("kryie", 25);
}
x++;
}
}
}
package pv;
public class Get implements Runnable{
private Student s;
public Get(Student s){
this.s = s ;
}
@Override
public void run() {
while(true){
s.get();
}
}
}
package pv;
public class StudentDemo {
public static void main(String[] args) {
//创建资源
Student s = new Student();
//设置资源、获取资源
Set st = new Set(s);
Get gt = new Get(s);
//线程类
Thread t1 = new Thread(st);
Thread t2 = new Thread(gt);
//启动线程
t1.start();
t2.start();
}
}