Java 학습노트24 - 스레드의 다중 스레드 안전, 잠금, 동기화 메커니즘
01라인 보안
/*
* 3 , ,
*/
public class ThreadDemo {
public static void main(String[] args) {
// Runnable
Tickets t = new Tickets();
// 3 Thread , Runnable
Thread t0 = new Thread(t);
Thread t1 = new Thread(t);
Thread t2 = new Thread(t);
t0.start();
t1.start();
t2.start();
}
}
/*
* ,
*/
public class Tickets implements Runnable{
//
private int ticket = 10;
private Object obj = new Object();
public void run(){
while(true){
// , 0, , --
if( ticket > 0){
try{
Thread.sleep(10); //
}catch(Exception ex){}
System.out.println(Thread.currentThread().getName()+" "+ticket--);
}
}
}
}
출력 결과: 창구 3 매표 10창구 2 매표 9창구 1 매표 8창구 1 매표 7창구 3 매표 7창구 2 매표 6창구 3 매표 5창구 1 매표 5창구 2 매표 4창구 3 매표 3창구 2 매표 2창구 1 매표 3창구 3 매표 3창구 3 매표 1창구 1 매표 0창구 2 매표 1창구 2 매표 1창구 1창구 1창구 1 매표 1창구 1창구 1창구 1에 다음과 같은 문제가 존재합니다. 표에 중복된 표 오류가 발생했습니다.표 0,-1은 여러 개의 라인이 변수에 대해 쓰기 작업을 동시에 수행하여 발생하는 라인 안전 문제입니다. 이 문제를 해결하려면 라인의 동기화를 고려해야 합니다.
/*
* 3 , ,
*/
public class ThreadDemo {
public static void main(String[] args) {
// Runnable
Tickets t = new Tickets();
// 3 Thread , Runnable
Thread t0 = new Thread(t);
Thread t1 = new Thread(t);
Thread t2 = new Thread(t);
t0.start();
t1.start();
t2.start();
}
}
public class Tickets implements Runnable{
//
private int ticket = 100;
private Object obj = new Object();
public void run(){
while(true){
// , ,
synchronized(obj){
// , 0, , --
if( ticket > 0){
try{
Thread.sleep(10);
}catch(Exception ex){}
System.out.println(Thread.currentThread().getName()+" "+ticket--);
}
}
}
}
}
public class Tickets implements Runnable{
//
private int ticket = 100;
public void run(){
while(true){
payTicket();
}
}
public synchronized void payTicket(){
if( ticket > 0){
try{
Thread.sleep(10);
}catch(Exception ex){}
System.out.println(Thread.currentThread().getName()+" "+ticket--);
}
}
}
02 Lock 커넥터
/*
* 3 , ,
*/
public class ThreadDemo {
public static void main(String[] args) {
// Runnable
Tickets t = new Tickets();
// 3 Thread , Runnable
Thread t0 = new Thread(t);
Thread t1 = new Thread(t);
Thread t2 = new Thread(t);
t0.start();
t1.start();
t2.start();
}
}
public class Tickets implements Runnable{
//
private int ticket = 100;
// , Lock
private Lock lock = new ReentrantLock();
public void run(){
while(true){
// Lock lock
lock.lock();
// , 0, , --
if( ticket > 0){
try{
Thread.sleep(10);
System.out.println(Thread.currentThread().getName()+" "+ticket--);
}catch(Exception ex){
}finally{
// , Lock unlock
lock.unlock();
}
}
}
}
}
synchronzied(A ){
synchronized(B ){
}
}
public class DeadLock implements Runnable{
private int i = 0;
public void run(){
while(true){
if(i%2==0){
// A , B
synchronized(LockA.locka){
System.out.println("if...locka");
synchronized(LockB.lockb){
System.out.println("if...lockb");
}
}
}else{
// B , A
synchronized(LockB.lockb){
System.out.println("else...lockb");
synchronized(LockA.locka){
System.out.println("else...locka");
}
}
}
i++;
}
}
}
public class DeadLockDemo {
public static void main(String[] args) {
DeadLock dead = new DeadLock();
Thread t0 = new Thread(dead);
Thread t1 = new Thread(dead);
t0.start();
t1.start();
}
}
public class LockA {
private LockA(){}
public static final LockA locka = new LockA();
}
public class LockB {
private LockB(){}
public static final LockB lockb = new LockB();
}
/*
* , 2
* name,sex
* 2 ,
* 1 name,age
* 2 name,age
*/
public class Resource {
public String name;
public String sex;
}
/*
* , Resource
* ,
* lisi,nv
*/
public class Input implements Runnable {
private Resource r=new Resource();
public void run() {
int i=0;
while(true){
if(i%2==0){
r.name=" ";
r.sex=" ";
}else{
r.name="lisi";
r.sex=" ";
}
i++;
}
}
}
/*
* , Resource ,
*/
public class Output implements Runnable {
private Resource r=new Resource() ;
public void run() {
while(true){
System.out.println(r.name+"..."+r.sex);
}
}
}
/*
* ,
*/
public class ThreadDemo{
public static void main(String[] args) {
Resource r = new Resource();
Input in = new Input();
Output out = new Output();
Thread tin = new Thread(in);
Thread tout = new Thread(out);
tin.start();
tout.start();
}
}
상기 Null 값 해결, 스레드 대기 및 깨우기 사례 null 값 해결
/*
* , Resource
* ,
* lisi,nv
*/
public class Input implements Runnable {
private Resource r;
public Input(Resource r){
this.r=r;
}
public void run() {
int i=0;
while(true){
if(i%2==0){
r.name=" ";
r.sex=" ";
}else{
r.name=" "
r.sex=" "
}
i++;
}
}
}
/*
* , Resource ,
*/
public class Output implements Runnable {
private Resource r;
public Output(Resource r){
this.r=r;
}
public void run() {
while(true){
System.out.println(r.name+"..."+r.sex);
}
}
}
}
/*
* ,
*/
public class ThreadDemo{
public static void main(String[] args) {
Resource r = new Resource();
Input in = new Input(r);
Output out = new Output(r);
Thread tin = new Thread(in);
Thread tout = new Thread(out);
tin.start();
tout.start();
}
}
이상 프로그램이 실행되고 출력된 결과 교차 착란대왕이 발견됩니다......남왕후......여왕 후......남대왕......여왕 후......여왕 후......여대왕......여왕 후......남왕후......남왕후......남대왕......여왕 후......남대왕......남자...솔루션:동기화 코드 블록 사용
/*
* , Resource
* ,
* lisi,nv
*/
public class Input implements Runnable {
private Resource r;
public Input(Resource r){
this.r=r;
}
public void run() {
int i=0;
while(true){
synchronized(r){
if(i%2==0){
r.name=" ";
r.sex=" ";
}else{
r.name=" "
r.sex=" "
}
i++;
}
}
}
/*
* , Resource ,
*/
public class Output implements Runnable {
private Resource r;
public Output(Resource r){
this.r=r;
}
public void run() {
while(true){
synchronized(r){
System.out.println(r.name+"..."+r.sex);
}
}
}
}
}
/*
* ,
*/
public class ThreadDemo{
public static void main(String[] args) {
Resource r = new Resource();
Input in = new Input(r);
Output out = new Output(r);
Thread tin = new Thread(in);
Thread tout = new Thread(out);
tin.start();
tout.start();
}
}
, ,
...남대왕......남대왕......남대왕......남대왕......남대왕......남대왕......남대왕......남자...해결 방안: 라인 대기 및 깨우기 입력 사용: 값을 부여한 후 실행 방법wait()는 출력을 영원히 기다린다. 변수 값은 출력을 출력하기 전에 입력한 notify()를 깨우고, 자신은wait()에서 입력을 영원히 기다린다. 깨어난 후 변수에 다시 값을 부여한다. 값을 부여한 후 출력된 라인 notify(), 자신의wait()를 깨워야 한다.
/*
* , 2
* name,sex
* 2 ,
* 1 name,age
* 2 name,age
*/
public class Resource {
public String name;
public String sex;
public boolean flag = false;
}
/*
* , Resource
* ,
* lisi,nv
*/
public class Input implements Runnable {
private Resource r ;
public Input(Resource r){
this.r = r;
}
public void run() {
int i = 0 ;
while(true){
synchronized(r){
// true,
if(r.flag){
try{r.wait();}catch(Exception ex){}
}
if(i%2==0){
r.name=" ";
r.sex=" ";
}else{
r.name=" "
r.sex=" "
}
// , true
r.flag = true;
r.notify();
}
i++;
}
}
}
/*
* , Resource ,
*/
public class Output implements Runnable {
private Resource r ;
public Output(Resource r){
this.r = r;
}
public void run() {
while(true){
synchronized(r){
// , false,
if(!r.flag){
try{r.wait();}catch(Exception ex){}
}
System.out.println(r.name+".."+r.sex);
// false,
r.flag = false;
r.notify();
}
}
}
}
/*
* ,
*/
public class ThreadDemo{
public static void main(String[] args) {
Resource r = new Resource();
Input in = new Input(r);
Output out = new Output(r);
Thread tin = new Thread(in);
Thread tout = new Thread(out);
tin.start();
tout.start();
}
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.